Python Django Admin Clean () Method not exceeding a value

Maybe something is missing me, but according to django docs, I can override the values ​​sent from the admin form from the clean () method. From django docs

def clean(self): from django.core.exceptions import ValidationError # Don't allow draft entries to have a pub_date. if self.status == 'draft' and self.pub_date is not None: raise ValidationError('Draft entries may not have a publication date.') # Set the pub_date for published items if it hasn't been set already. if self.status == 'published' and self.pub_date is None: self.pub_date = datetime.date.today() 

I deleted my code and just trying to make a basic example from inside admin

Models.py

 class Test(models.Model): name = models.CharField(max_length=255,) def clean(self): self.name = 'Robin Hood' return self 

Therefore, when I try to add a new test record, if I leave the name field blank, it should capture the value from the pure method and save.

What happens is that the form does not check, and the field remains empty.

Did I miss something more obvious here?

+6
source share
5 answers

You won’t even get to launch the model cleanup method. Django will run the form validation code first, and since your field is not defined using blank=True , the form will enforce this restriction.

What you have to do is redefine the form by setting required=False in the name field, and then write a form cleanup method that sets the values ​​to - and returns - self.cleaned_data :

 class TestForm(forms.ModelForm): name = forms.CharField(required=False) class Meta: model = Test def clean(self): self.cleaned_data['name'] = 'Robin Hood' return self.cleaned_data 

and refer to this form in your admin class:

 class TestAdmin(admin.ModelAdmin): form = TestForm 
+4
source

clean() method of the model is not called when objects are created from the admin site. clean() is called only after full_clean() , but saving and the object on the Django admin site does not call this function.

As you can see in the official documentation for Mode.clean () mode, full_clean () is called to catch additional validation errors.

 from django.core.exceptions import ValidationError, NON_FIELD_ERRORS try: article.full_clean() except ValidationError, e: non_field_errors = e.message_dict[NON_FIELD_ERRORS] 

To do this, you need to override the save () method.

+2
source

2 small steps to solve this problem :)

1) full_clean () is called before clean (), so set pub_date in models.py as:

 pub_date = models.DateField(null=True) 

2) just return the cleaned_data dict from the pure function to manipulate the value of the pub_date model field. Try the following:

 def clean(self): from django.core.exceptions import ValidationError # Don't allow draft entries to have a pub_date. if self.cleaned_data['status'] == 'draft' and self.cleaned_data['pub_date'] is not None: raise ValidationError('Draft entries may not have a publication date.') # Set the pub_date for published items if it hasn't been set already. if self.cleaned_data['status'] == 'published' and self.cleaned_data['pub_date'] is None: self.cleaned_data['pub_date'] = datetime.date.today() return self.cleaned_data 
  • have mercy on other developers and import a ValidationError on top of the forms.py file, and then import it into each clean function, and then :)
+2
source

try it. You need to return all cleared data. In addition, you will need to set blank=True in the form field so that it is empty if you have not already done so.

 def clean(self,*args,**kwargs): cleaned_data = super(Test,self).clean(*args,**kwargs) # Check to see if name is entered, if not set it to robin hood. if not cleaned_data['name']: cleaned_data['name'] = 'Robin Hood' return cleaned_data 
+1
source

Suppose you have a model with three fields field1, 2 and 3, and you want to set field3 as a combination of fields1 and field2, you can write this:

 class MyModel(models.Model): field1 = ... field2 = ... field3 = ... def clean(self): #simply set field3 as the value you want, and note that RETURN is NOT NEEDED in this function self.field3 = "%s-%s" % (self.field1, self.field2) 
+1
source

All Articles