Maybe I am missing something here, but according to the django docs, I should be able to overide values sent from an admin form from within 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 have stripped down my code and am just trying a basic example here from within the admin
Models.py
class Test(models.Model):
name = models.CharField(max_length=255,)
def clean(self):
self.name = 'Robin Hood'
return self
So when I try and add a new Test record, if I leave the name field empty, it should grab the value from the clean method and save.
What happens though, is that the form doesnt validate, and the field remains empty.
Am I missing something blantantly obvious here?
The clean() method on a Field subclass is responsible for running to_python() , validate() , and run_validators() in the correct order and propagating their errors. If, at any time, any of the methods raise ValidationError , the validation stops and that error is raised.
save() calls the clean. This way the integrity is enforced both from forms and from other calling code, the command line, and tests. Without this, there is (AFAICT) no way to write a test that ensures that a model has a FK relation to a specifically chosen (not default) other model.
If yes try to disable this behavior, set the novalidate attribute on the form tag As <form action="{% url 'new_page' %}", method="POST" novalidate> in your html file.
You won't even get as far as running the model clean method. Django will run the form's validation code first, and because your field is not defined with blank=True
, the form will enforce that constraint first.
What you should do is to override the form, setting required=False
to the name
field, then writing a form clean method which sets values in - 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 reference that form in your admin class:
class TestAdmin(admin.ModelAdmin):
form = TestForm
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With