Reputation: 10162
I came across this code:
drinker/models.py:
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
class Drinker(models.Model):
user = models.OneToOneField(User)
birthday = models.DateField()
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
drinker/forms.py:
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from drinker.models import Drinker
class RegistrationForm(ModelForm):
username = forms.CharField(label=(u'User Name'))
email = forms.EmailField(label=(u'Email Address'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput(render_value=False))
class Meta:
model = Drinker
exclude = ('user',)
def clean_username(self):
username = self.cleaned_data['username']
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError("That username is already taken, please select another.")
def clean(self):
if self.cleaned_data['password'] != self.cleaned_data['password1']:
raise forms.ValidationError("The passwords did not match. Please try again.")
return self.cleaned_data
My Question is about the inner class meta which as two attributes:
model=Drinker
exclude=('user`,)
I have a not-so-clear understanding of how this meta class
work. I have read the documentation
but I am still confused. Can you kindly explain what those two lines mean and what their purpose is?
Thanks
Upvotes: 8
Views: 11083
Reputation: 1124248
The exclude
attribute tells Django what fields from the model not to include in the form.
Quoting the Selecting fields to use section of the model form documentation:
2. Set the
exclude
attribute of theModelForm
’s inner Meta class to a list of fields to be excluded from the form.
The model
line simply tells Django what model to take the fields from; together the two lines tell Django to give RegistrationForm
fields based on all fields on the Drinker
model, except 'user'
. For the given Drinker
model, that's birthday
and name
.
These fields are added to the other form fields already defined on the form. If the Drinker
model gained more fields, those would automatically be part of the form too.
See the Overriding the default fields section of the same chapter:
When you explicitly instantiate a form field like this, it is important to understand how
ModelForm
and regularForm
are related.
ModelForm
is a regularForm
which can automatically generate certain fields. The fields that are automatically generated depend on the content of theMeta
class and on which fields have already been defined declaratively. Basically,ModelForm
will only generate fields that are missing from the form, or in other words, fields that weren’t defined declaratively.
The inner Meta
class is just a convenient way to create a namespace for such configuration on your form class for the Django framework to find. All Django now has to do is introspect Form.Meta
and see what attributes are defined there.
Note that using exclude
can lead to security problems. From the same documenation:
It is strongly recommended that you explicitly set all fields that should be edited in the form using the fields attribute. Failure to do so can easily lead to security problems when a form unexpectedly allows a user to set certain fields, especially when new fields are added to a model. Depending on how the form is rendered, the problem may not even be visible on the web page.
The alternative approach would be to include all fields automatically, or blacklist only some. This fundamental approach is known to be much less secure and has led to serious exploits on major websites (e.g. GitHub).
Upvotes: 10
Reputation: 11
fields = exclude() and fields = '__all__'
- means display all the fields
exclude = ('password',)
- means exclude password field
fields = ('user','email',)
- means display only email field and userfield
Upvotes: 1
Reputation: 2209
in short : fields you want to show up in the form should be mentioned in 'fields' attribute ex:
fields = '__all__' #will show all the fields from the model in the form
'exclude' does the opposite
exclude = ['title'] # don't show the title field
Upvotes: 0