Reputation: 467
When I type form.is_valid() (being form a modelForm of a model I made) django throws me the following exception:
ValueError: Cannot assign None: "Membership.member" does not allow null values.
But when I validate again, I get that the form is true.
>>> User.objects.get(id=2L)
<User: [email protected]>
>>> data={'member': 2L, 'membership_role': 3L, 'read_access': True, 'research': 2L}
>>> f=ResearchFormStepTwo(data=data)
>>> f.is_valid()
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/forms/forms.py", line 126, in is_valid
return self.is_bound and not bool(self.errors)
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/forms/forms.py", line 117, in _get_errors
self.full_clean()
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/forms/forms.py", line 274, in full_clean
self._post_clean()
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/forms/models.py", line 315, in _post_clean
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/forms/models.py", line 52, in construct_instance
f.save_form_data(instance, cleaned_data[f.name])
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 466, in save_form_data
setattr(instance, self.name, data)
File "/home/django/virtualenvs/patman/lib/python2.7/site-packages/django/db/models/fields/related.py", line 401, in __set__
(instance._meta.object_name, self.field.name))
ValueError: Cannot assign None: "Membership.member" does not allow null values.
>>> f.is_valid()
True
The stack trace does not include code of my own (only django libraries).
My model is:
class Membership(models.Model):
member=models.ForeignKey(PatmanUser,on_delete=models.CASCADE,db_index=False)
research=models.ForeignKey(Research,on_delete=models.CASCADE)
membership_role=models.ForeignKey(Role,default=Role.get_sentinel_role,on_delete=models.SET_DEFAULT,db_index=False)
read_access=models.BooleanField(default=True,db_index=False)
write_access=models.BooleanField(default=False,db_index=False)
def clean(self, *args, **kwargs):
if self.pk is None and self.read_access==False and self.write_access==False:
raise ValidationError('No es posible pertenecer a un estudio sin permisos definidos')
if Membership.objects.filter(member=self.member,research=self.research).count()>1:
raise ValidationError('No puede haber dos pertenencias de un usuario a un estudio')
if not self.member.is_active:
raise ValidationError('El usuario no esta activo')
if self.read_access==False and self.write_access==True:
raise ValidationError('No puede tener permisos de escritura y no de lectura')
super(Membership,self).clean(*args, **kwargs)
def save(self, *args, **kwargs):
if self.pk is not None and self.read_access==False and self.write_access==False:
real_object=Membership.objects.get(pk=self.pk)
real_object.delete()
else:
super(Membership, self).save(*args, **kwargs)
class Meta:
verbose_name = "Miembro"
verbose_name_plural = "Miembros"
index_together = [
["member","read_access"],
["member","write_access"]
]
def __unicode__(self):
return u"%s %s role:%s read:%s write:%s" % (self.member,self.research,self.membership_role,self.read_access,self.write_access)
My modelform is:
class ResearchFormStepTwo(ModelForm):
class Meta:
model = Membership
def clean_member(self):
data = self.cleaned_data
member=data.get("member")
if not member.is_active:
raise forms.ValidationError("El usuario no esta activado")
def __unicode__(self):
return self.data
Upvotes: 1
Views: 2858
Reputation: 14046
You need to return the member
instance in .clean_member()
when
it's valid. The missing return
is an implicit None
, which then
causes the ValueError
since Membership.member
isn't optional.
class ResearchFormStepTwo(ModelForm):
class Meta:
model = Membership
def clean_member(self):
data = self.cleaned_data
member = data.get("member")
if not member.is_active:
raise forms.ValidationError("El usuario no esta activado")
return member
def __unicode__(self):
return self.data
https://docs.djangoproject.com/en/1.5/ref/forms/validation/#cleaning-a-specific-field-attribute
Upvotes: 3