Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override the initialization of a ChoiceField in django

I am trying to initialize a form containing a ChoiceField in django. I have the following code:

# 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()]

but oon the shell, once I try to instanciate:

r = RegisterForm(username="toto", email="[email protected]")

I receive 'RegisterForm' object has no attribute 'fields' error. Is this happening as the object is not already formed? How can I access to the ChoiceField?

Any help appreciated.

like image 218
Juan Chô Avatar asked Dec 11 '25 21:12

Juan Chô


1 Answers

You're not using the Form object in the good way. The fields attribute is initialize by the __init__ method of BaseForm (see the source code) (a parent class of forms.Form), but you have redefine it, so you broke the process.

So, you should call the parent __init__ in your __init__ method, something like this:

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()]

I have moved every *Field declaration outside the __init__, because it's the common way. It's question is very similar to a previous one: Override defaults attributes of a Django form

like image 90
Maxime Lorant Avatar answered Dec 13 '25 12:12

Maxime Lorant