Django管理员中的自定义验证

Ami*_*tad 34 python django django-forms django-admin django-validation

我有一个非常简单的Django应用程序,以记录给我的同事的讲座.由于它是相当基本的,我使用Django管理员本身.这是我的models.py:

#models.py
from django.db import models

class Lecture(models.Model):
    topic = models.CharField(max_length=100)
    speaker = models.CharField(max_length=100)
    start_date = models.DateField()
    end_date = models.DateField()
Run Code Online (Sandbox Code Playgroud)

我需要确保没有人在管理表单中的结束日期之后输入开始日期,所以我在管理员中阅读了django文档以进行自定义验证,并在我的admin.py中实现了以下内容:

#admin.py
from models import Lecture
from django.contrib import admin
from django import forms


class LectureForm(forms.ModelForm):
    class Meta:
        model = Lecture

        def clean(self):
            start_date = self.cleaned_data.get('start_date')
            end_date = self.cleaned_data.get('end_date')
            if start_date > end_date:
                raise forms.ValidationError("Dates are incorrect")
        return self.cleaned_data


class LectureAdmin(admin.ModelAdmin):
    form = LectureForm
    list_display = ('topic', 'speaker', 'start_date', 'end_date')

admin.site.register(Lecture, LectureAdmin)
Run Code Online (Sandbox Code Playgroud)

但是,这对我的管理员没有任何影响,我可以保存讲座,其中start_date位于end_date之后,如图所示:在此输入图像描述

我究竟做错了什么 ??

Dan*_*man 24

你有一个缩进问题.您的clean方法在表单的Meta类中缩进.将其向后移动一级.另外,请确保return语句在方法中缩进.

  • 您可以定义 [`get_changelist_form`](https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_changelist_form) 方法以返回自定义表单以在那里使用. (2认同)

ari*_*ris 18

通常,您只想在模型本身上定义clean()方法。

https://docs.djangoproject.com/zh-CN/2.1/ref/models/instances/#validating-objects

from django.core.exceptions import ValidationError

class Lecture(models.Model):
    topic = models.CharField(max_length=100)
    speaker = models.CharField(max_length=100)
    start_date = models.DateField()
    end_date = models.DateField()

    def clean(self):
        if self.start_date > self.end_date::
            raise ValidationError("Dates are incorrect")
Run Code Online (Sandbox Code Playgroud)

这样的事情将在django管理员中运行,而无需创建表单类。

  • 请记住,模型的“clean()”方法不会通过“save()”自动调用。这在管理页面中有效,因为它的表单为您调用“clean()”方法。您仍然需要在其他地方的 `save()` 之前调用 `clean()`。来自文档:[“但是请注意,像 Model.full_clean() 一样,当您调用模型的 save() 方法时,不会调用模型的 clean() 方法。”](https://docs.djangoproject.com/ en/dev/ref/models/instances/#django.db.models.Model.clean) (3认同)
  • 很好的解决方案。我从事Django的工作已经很多年了,对此我一无所知。谢谢! (2认同)