2013-08-30 4 views
1

Я пытаюсь инициализировать форму, содержащую ChoiceField в django. У меня есть следующий код:Переопределить инициализацию ChoiceField в django

# in file models.py 
class Locality(models.Model): 
    locality = models.CharField(primary_key=True, unique=True, max_length=36) 
    def __unicode__(self): 
     return self.locality 

# in file forms.py 
class RegisterForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     self.username = forms.CharField(required=True) 
     self.email = forms.EmailField(required=True) 
     self.locality = forms.ChoiceField(widget=forms.Select()) 
     self.fields['locality'].choices = [l.locality for l in Locality.objects.all()] 

но Ун оболочки, когда я пытаюсь создать экземпляр:

г = RegisterForm (имя пользователя = "Toto", электронная почта = "а @ Ь .com ")

Я получаю 'RegisterForm' object has no attribute 'fields' error. Это происходит, поскольку объект еще не сформирован? Как я могу получить доступ к ChoiceField?

Любая помощь приветствуется.

ответ

4

Вы не используете объект Form в хорошем смысле. Атрибут fields инициализируется by the __init__ method of BaseForm (see the source code) (родительский класс forms.Form), но вы его переопределили, поэтому вы нарушили этот процесс.

Таким образом, вы должны позвонить родителям __init__ в методе __init__, что-то вроде этого:

class RegisterForm(forms.Form): 
    username = forms.CharField(required=True) 
    email = forms.EmailField(required=True) 
    locality = forms.ChoiceField(widget=forms.Select()) 

    def __init__(self, *args, **kwargs): 
     super(forms.Form, self).__init__(*args, **kwargs) 
     self.fields['locality'].choices = [(l.id, l.locality) for l in Locality.objects.all()] 

Я переехал каждую *Field декларацию вне __init__, потому что это общий путь. Это вопрос очень похож на предыдущий: Override defaults attributes of a Django form

+0

почему нет «» супер «»? – mawimawi

+0

Обновлено, как раз перед тем, как я увижу ваш комментарий –

+0

'self.fields ['locality']. Choice = [l.lality для l в Locality.objects.all()]' неверно. вы должны использовать 'self.fields ['locality']. choice = [(l.id, l.lality) для l в Locality.objects.all()]' i означает, что выбор должен быть в формате '[(.., ..), (.., ..), ..] ' – suhailvs

0

попробовать:

def __init__(self, *args, **kwargs): 
    super(forms.Form, self).__init__(*args, **kwargs) 
    self.fields['locality'].choices = [(l.id, l.locality) for l in Locality.objects.all()] 
+0

Список будет создан при объявлении формы. Если он добавит новое значение в Locality после запуска сервера, это новое значение не будет в списке выбора. Вместо этого функция '__init__' вызывается каждый раз, когда вы создаете новую форму. –

+0

@MaximeLorant выбор должен быть в формате '[(.., ..), (.., ..), ..]' – suhailvs

+0

@MaximeLorant Я использую эту методологию во всех своих проектах, и она отлично работает. – suhailvs

Смежные вопросы