Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Django Admin Clean() Method not overiding values

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?

like image 292
user1016190 Avatar asked Jan 23 '13 19:01

user1016190


People also ask

What is clean method in Django?

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.

Does Django save call clean?

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.

How do you remove this field is required Django?

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.


1 Answers

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
like image 113
Daniel Roseman Avatar answered Sep 20 '22 17:09

Daniel Roseman