2

I'm working on a blog for Django, and I would like to use the Django admin's built in validation. However, I would like some way to disable validation if the blog post status is set to "draft".

Basically, I'm looking for code that should do something like this:

def validate(self, **kwargs):
    ''' do not validate drafts '''
    if self.status != Post.STATUS_DRAFT:
        Super(Post, self).validate(**kwargs)
Joshmaker
  • 4,068
  • 3
  • 27
  • 29
  • See http://stackoverflow.com/questions/676931/creating-an-entire-web-application-using-django-admin Particularly, "the admin is not your app" part. – Andrew Sledge Dec 27 '10 at 18:01

1 Answers1

3

You can't not validate forms. The role of form validation is to make sure that, for example, a value that should contain a number contains a number. The fact that you believe the post to be in "draft" mode does not excuse the necessity of a date field to contain a date rather than a string of meaningless text.

I imagine what you want is to allow certain fields to be required in normal mode, but optional in draft mode.

In which case, this is done on the model level. You can use a custom admin form to enforce this behavior:

# models.py
...
class Post(models.Model):
    title = models.CharField(..., null=True, blank=True)
    fliddle = models.IntegerField(..., null=True, blank=True)
    published = models.BooleanField() # if false, then in draft mode


# admin.py
...
class BlogForm(forms.ModelForm):
    class Meta:
        model = Post

    title = forms.CharField(..., required=False)
    fliddle = forms.IntegerField(..., required=False)

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.get('instance', None)
        super(BlogForm, self).__init__(*args, **kwargs)

    def clean_title(self):
        data = self.cleaned_data.get('title',None)
        if self.instance and self.instance.published == True and not data:
            raise forms.ValidationError("Title is required.")
        return data

    def clean_fliddle(self):
        data = self.cleaned_data.get('fliddle',None)
        if self.instance and self.instance.published == True and not data:
            raise forms.ValidationError("Fliddle is required.")
        return data

class BlogAdmin(admin.ModelAdmin):
    class Meta:
        model=Blog
    form = BlogForm

admin.site.register(Blog, BlogAdmin)
Jordan Reiter
  • 20,467
  • 11
  • 95
  • 161
  • I'd just like to add that in all seriousness, the only thing you can choose to not validate for is the presence or absence of an optional field. If the field is required in the database, it must be validated for in the model and form. If it must be in a particular format, you must validate that it is in that format. – Jordan Reiter Dec 27 '10 at 18:25