如何仅在添加时验证Django表单而非编辑时

3 投票
5 回答
3149 浏览
提问于 2025-04-16 06:16

我们怎么才能让Django表单在编辑时不进行验证,而只在添加新记录时进行验证呢?下面是相关代码:

class PageForm(forms.Form):
    name = forms.CharField(max_length=100,widget=forms.TextInput(attrs={'class':'textInput'}))
    description = forms.CharField(max_length=300, required=False,widget=forms.TextInput(attrs={'class':'textInput'}))
    body = forms.CharField(widget=forms.Textarea)
    template = forms.CharField(max_length=30,widget=forms.TextInput(attrs={'class':'textInput'}))
    navbar = forms.BooleanField(required=False, widget=forms.Select(choices=(('True','True'),
                                                                             ('False', 'False'))))
    publish = forms.BooleanField(widget=forms.Select(choices=(('Published','Publish Now'),
                                                              ('Private','Private'),
                                                              ('Draft','Draft'))))

    def save(self, page=None, commit=True):
        data = self.cleaned_data
        if not page: 
            page = models.Page(key_name=data['name'].replace(' ','-'))
        page.name = data['name']
        page.description = data['description']
        page.body = data['body']
        page.template = data['template']
        page.publish = data['publish']
        if commit: page.put()
        return page


    # prevent the same page 's name
    def clean_name(self):
        name = self.cleaned_data['name']
        query = models.Page.all(keys_only=True)
        query.filter('name = ', name)

        page = query.get()

        if page:
            raise forms.ValidationError('Page name "%s" was already used before' % name)

        return name

这个名字验证的目的是为了防止出现同名的记录。但是我发现,在编辑的时候也会进行验证,这样我们就无法编辑记录,因为系统会提示“同名记录已经存在”。

其实在编辑的时候,保存函数中的页面参数不会是空的,而是之前的记录;而在保存新记录时,这个参数会是空的。那么我们该如何在clean_name函数中读取这个参数,以便判断是编辑还是创建呢?

非常感谢!

5 个回答

1

在你的 clean_name 函数中,要把当前对象从查询结果中排除掉。

query.filter('name = ', name).exclude(pk=self.pk)

或者,你可以修改一下 if 条件,检查一下页面和当前对象是不是同一个。

2

如果你正在编辑一个表单,那么这个表单就有一个实例,你可以检查这个实例是否存在。

如果存在的话,那你可能是在编辑一个已经存在的对象,对吧?

举个例子:如果你正在用表单编辑一个对象,你可以像这样创建表单对象:

form = MyForm(instance = myobject)

然后在你的表单类的方法里,你可以检查这个表单是否有保存的实例,具体的方式可以参考这里的描述:

测试Django ModelForm是否有实例

3

在你的清理方法中,你可以使用 self.initial 来判断是添加新内容还是编辑已有内容。如果是在编辑,self.initial 就不会是空的。但是如果是在添加新内容,self.initial 就会是一个包含之前值的字典。

撰写回答