【问题标题】:Modified Django admin clean() method not being invoked修改后的 Django admin clean() 方法未被调用
【发布时间】:2018-04-13 20:20:14
【问题描述】:

我基于 Django 管理站点开发了一个工具(内部使用)。

我有模型验证器可以很好地工作,但是为了进行更复杂的验证,我试图覆盖 admin.py 中的 clean() 方法

我的 admin.py 看起来像这样:


from django.contrib import admin
from .models import Provider, Employer, Person, Learnership, Qualification, Unit_Standard
from django import forms

class ProviderForm(forms.ModelForm): class Meta: model = Provider fields = 'all'

    def clean(self):
        provider_start_date = self.cleaned_data.get('provider_start_date')
        provider_end_date = self.cleaned_data.get('provider_end_date')
        if provider_start_date > provider_end_date:
            raise forms.ValidationError("Start date can't be after end date")
        return self.cleaned_data

admin.site.register(Provider)

提供者模型的 models.py:


class Provider(models.Model):
    ... lots of stuff here ...
    provider_start_date = models.DateField()
    provider_end_date = models.DateField(blank=True, null=True)
    ... lots of stuff here ...

    def __str__(self):
        return '%s %s' % (self.provider_name, self.provider_code)

问题是 admin.py 中显示的代码似乎没有触发,您可以将结束日期保存在开始日期之前的记录。

Django 管理界面确实是该框架的一个了不起的功能,我认为其他人可能也遇到了无法进行更高级验证的问题,因此它也会对他们有所帮助。

【问题讨论】:

  • 请修正缩进
  • 注意应该是fields = '__all__',而不是'all'

标签: python django django-models django-admin


【解决方案1】:

你应该调用 super() int clean 方法:

def clean(self):

    cleaned_data = super(ProviderForm, self).clean()

编辑:

这不是正确的答案,上面的@Alasdair 是。正如@scharette 在 cmets 中指出的那样

只有当你的表单继承了另一个没有 在其 clean() 方法中返回一个cleaned_data 字典。另外,如果 你使用的是 python 3 不需要参数

【讨论】:

  • 只有当你的表单继承了另一个在其clean() 方法中不返回clean_data 字典时,这才相关。此外,如果您使用的是 python 3,则不需要参数。
  • 你应该明确地编辑你的答案,参考 Alasdair 的答案并添加我的澄清,因为这是一个很好的观点,只是错误地陈述。
  • 不错的见解。
【解决方案2】:

你已经创建了一个模型表单,但是你没有告诉 Django 使用它。

您应该创建一个模型管理员,并将form 设置为您的模型表单:

class ProviderAdmin(admin.ModelAdmin):
    form = ProviderForm

然后在你的模型管理类中注册你的模型:

admin.site.register(Provider, ProviderAdmin)

【讨论】:

    【解决方案3】:

    考虑到您的缩进只是发布代码的问题,我猜您忘记覆盖管理类。以下是您需要做的:

    class ProviderAdmin(admin.ModelAdmin):
        form = ProviderForm
    
    
    admin.site.register(Provider,ProviderAdmin)
    

    您走在正确的道路上,您只是忘记通过使用clean override 指定表单来在管理类上注册覆盖

    【讨论】:

    • 非常感谢,它有效 - 我真的不知道 StackOverflow 的协议,但我猜我需要将第一个答案标记为正确,即使你们都正确?
    • 您可以将任何您想要的答案标记为正确,it doesn't need to be the first one
    • 你接受他的做法是正确的,因为这完全一样,而且他是第一个。很高兴它有帮助!感谢@Alasdair +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2012-11-18
    • 2014-03-04
    • 2012-07-08
    • 1970-01-01
    • 2010-10-13
    相关资源
    最近更新 更多