Django唯一约束+表单错误

时间:2010-08-13 00:59:32

标签: django constraints unique relational-database

我在网站上发布双重帖子时遇到了一些问题。我认为所有相关领域的简单唯一约束将解决数据库级别的问题,但它只会为用户生成一个讨厌的错误页面。有没有办法可以把它变成漂亮的形式错误呢?像non_field_error一样?或者我应该采取什么方法?

2 个答案:

答案 0 :(得分:11)

也许这样的事情可以帮到你:

class YourForm(forms.Form):
    # Everything as before.
    ...

    def clean(self):
        cleaned_data = self.cleaned_data
        your_unique_key = cleaned_data['your_unique_key']

        if your_unique_key and YourModel.objects.get(your_unique_key=your_unique_key):
            raise forms.ValidationError("not unique")

        # Always return the full collection of cleaned data.
        return cleaned_data

clean()方法将允许您访问表单中的所有字段,如果您具有组合的唯一键,则可能非常有用。否则(短得多)clean_your_unique_key()可能会更适合你。

请注意,在极少数情况下(竞争条件),表单验证可能不会报告重复的条目(但它当然是由数据库引擎报告的)。但是对于大多数应用程序来说,提供的示例将更容易,更易于维护,因此我仍然推荐这种方法。

答案 1 :(得分:1)

就用户而言,“令人讨厌的错误页面”,Django允许您自定义自己的500,404以及其他可能的页面。一般信息:

  

为了使用Http404异常   最充分的,你应该创造一个   404时显示的模板   提出错误。这个模板应该   被称为404.html并位于   模板树的顶级。

- http://docs.djangoproject.com/en/dev/topics/http/views/

另一种不错的方式,不是像tux21b的解决方案那样DRY,但对于一次性解决方案可能更容易理解,可能是智能地捕获错误。一种方法是这样做,甚至没有打扰违反约束 - 一个简单的查询应该验证用户是否要做违法的事情。

okToUpdate=MyModel.objects.filter(parameters=values...).count()  

if okToUpdate>0:  # an object already exists  
    errorExists=True  
    errors={customError:customMessage}  

...  

if errorExists:  
     return render_to_response(errors,'customErrorPage.html')  

else:  
    # return whatever you normally would return  

然后使用render_to_response呈现自定义错误页面。

(另一种方法是允许数据库违规发生,然后捕获该错误并执行相同的操作......我认为数据库获得的查找压力略小于处理异常,但这取决于你如何喜欢做事。)

JB