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

时间:2013-01-23 19:41:12

标签: python django admin

也许我在这里遗漏了一些东西,但是根据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()

我已经删除了我的代码,我只是在管理员

中尝试了一个基本示例

Models.py

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

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

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

但是,表单没有验证,字段仍为空。

我在这里错过了一些明显的东西吗?

5 个答案:

答案 0 :(得分:5)

您甚至无法运行模型清理方法。 Django将首先运行表单的验证代码,并且由于您的字段未使用blank=True定义,表单将首先强制执行该约束。

您应该覆盖表单,将required=False设置为name字段,然后编写表单 clean方法,该方法将值设置为 - 并返回 - { {1}}:

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

答案 1 :(得分:2)

从管理站点创建对象时,不会调用

clean()模型方法。仅在clean()之后调用full_clean(),但在Django管理站点上保存和对象不会调用该函数。

正如您在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()方法。

答案 2 :(得分:2)

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

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

pub_date = models.DateField(null=True)

2)只需从clean函数返回cleaning_data dict来操作pub_date模型字段值。试试这个:

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,而不是在每个clean函数中导入它然后:)

答案 3 :(得分:1)

试试这个。您需要返回所有已清理的数据。此外,您需要在表单字段中设置blank=True,以便在您尚未填写时将其设为空白。

def clean(self,*args,**kwargs):
    cleaned_data = super(Test,self).clean(*args,**kwargs)

    # Check to see if name is entered, if not set it to robin hood. 
    if not cleaned_data['name']:
        cleaned_data['name'] = 'Robin Hood'

    return cleaned_data

答案 4 :(得分:1)

假设您的模型包含三个字段field1,2和3,并且您希望将field3设置为field1和field2的组合,您可以这样写:

class MyModel(models.Model):
    field1 = ...
    field2 = ...
    field3 = ...

    def clean(self):
        #simply set field3 as the value you want, and note that RETURN is NOT NEEDED in this function
        self.field3 = "%s-%s" % (self.field1, self.field2)