Django admin 中的自定义验证

Posted

技术标签:

【中文标题】Django admin 中的自定义验证【英文标题】:Custom validation in Django admin 【发布时间】:2014-09-08 05:57:32 【问题描述】:

我有一个非常简单的 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()

我需要确保没有人在管理表单中的结束日期之后输入开始日期,因此我阅读了 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)

但是,这对我的管理员没有任何影响,我可以保存 start_date 在 end_date 之后的讲座,如图所示:

我做错了什么??

【问题讨论】:

【参考方案1】:
def clean(self): 
   if self.database_name != '111':
      raise ValidationError("You can use only letters ,numbers and 
      underscores.")

这种干净的方法在 django admin 中非常适合我

【讨论】:

【参考方案2】:

通常你只想在模型本身上定义一个 clean() 方法。

https://docs.djangoproject.com/en/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")

类似的东西可以在 django admin 中工作,而无需创建表单类。

【讨论】:

在我的情况下,虽然引发了错误,但即使在引发错误后仍然可以保存对象 请记住,模型的clean() 方法不会使用save() 自动调用。这适用于管理页面,因为它的表单为您调用 clean() 方法。您仍然需要在其他地方拨打save() 之前拨打clean()。来自文档:"Note, however, that like Model.full_clean(), a model’s clean() method is not invoked when you call your model’s save() method."【参考方案3】:

您有缩进问题。您的 clean 方法在表单的 Meta 类中缩进。将其移回一层。此外,请确保 return 语句在方法中缩进。

【讨论】:

那行得通!!..我几乎花了 2 个小时重新阅读文档来修复它!!..我还有一个疑问..验证错误仅在我出现时才抛出创建了一个新条目。对于现有条目,它们继续存在。我假设仅在保存模型时调用 clean() 方法。如何确保每次加载页面时都调用它? @Amistad clean 方法仅在提交表单时调用,而不是“在保存模型时”(如果这是您想要的,您正在寻找模型的验证:docs.djangoproject.com/en/1.7/ref/models/instances/…) ...“每次页面加载时”仍然不会验证您的模型实例,但是为什么您仍然想要这样的“功能”? 嗯..现在我想起来了,我对模型的所有更改都只能通过管理员通过表单发生..所以那里的验证检查就足够了..谢谢.. 您可以定义get_changelist_form 方法以返回自定义表单以供在那里使用。 以防万一它可以帮助其他人:请注意,重要的是导入“from django.forms import ValidationError”而不是“from django.core.exceptions import ValidationError”

以上是关于Django admin 中的自定义验证的主要内容,如果未能解决你的问题,请参考以下文章

Django admin 中的自定义相关下拉菜单

django admin changelist_view 中的自定义 html 字段

Django 1.3 或更低版本的 Django Admin 中的自定义过滤器

基于列表显示中的自定义可调用在 Django Admin 中排序

django中的admin组件之自定义组件的增删改查的完善

JWT 身份验证不适用于 Django 中的自定义控制器