Python Django Admin Clean()方法不覆盖值

2024-06-01 23:12:03 发布

您现在位置:Python中文网/ 问答频道 /正文

也许我在这里遗漏了一些东西,但是根据django文档,我应该能够在clean()方法中覆盖从管理表单发送的值。 来自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()

我已经精简了我的代码,只是在这里尝试一个基本的例子

模型.py

class Test(models.Model):
name = models.CharField(max_length=255,)

def clean(self):
    self.name = 'Robin Hood'
    return self

因此,当我尝试添加一个新的测试记录时,如果我将name字段留空,它应该从clean方法中获取值并保存。

但是,发生的情况是表单没有验证,并且字段保持为空。

我是不是遗漏了一些显而易见的东西?


Tags: django方法nameselfclean表单dateif
3条回答

从管理站点创建对象时,不调用模型的clean()方法。clean()只在full_clean()之后调用,但Django管理站点上的Saving和object不调用该函数。

official documentation for Mode.clean()中可以看到,调用full_clean()来捕获额外的验证错误。

from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
    article.full_clean()
except ValidationError, e:
    non_field_errors = e.message_dict[NON_FIELD_ERRORS]

为此,需要重写save()方法。

你甚至连运行模型清理方法都做不到。Django将首先运行表单的验证代码,并且因为您的字段不是用blank=True定义的,所以表单将首先执行该约束。

您应该做的是重写表单,将required=False设置为name字段,然后编写一个formclean方法,该方法在-中设置值并返回-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

并在管理类中引用该表单:

class TestAdmin(admin.ModelAdmin):
    form = TestForm

解决此问题的两个小步骤:)

1)在clean()之前调用full_clean(),因此在models.py中将pub_date设置为:

pub_date = models.DateField(null=True)

2)只需从clean函数返回cleaned_data dict即可操作pub_date model字段值。请尝试以下操作:

def clean(self):
    from django.core.exceptions import ValidationError
    # Don't allow draft entries to have a pub_date.
    if self.cleaned_data['status'] == 'draft' and self.cleaned_data['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.cleaned_data['status'] == 'published' and self.cleaned_data['pub_date'] is None:
       self.cleaned_data['pub_date'] = datetime.date.today()
    return self.cleaned_data
  • 怜悯其他开发人员,在forms.py文件上导入ValidationError,而不是时不时地在每个干净的函数中导入它:)

相关问题 更多 >