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