代码之家  ›  专栏  ›  技术社区  ›  mpen

Django唯一约束+表单错误

  •  4
  • mpen  · 技术社区  · 14 年前

    我在我的网站上有一些双重张贴的问题。我认为,跨所有相关字段的一个简单的唯一约束将在数据库级别解决问题,但它只会为用户生成一个糟糕的错误页。有没有办法把它变成一个漂亮的形式错误呢?就像一个 non_field_error

    2 回复  |  直到 14 年前
        1
  •  13
  •   tux21b    14 年前

    也许这样的东西能帮你:

    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() 方法将允许您访问窗体的所有字段,如果您有一个组合的唯一键,那么这些字段可能会很有用。否则a(略短) clean_your_unique_key()

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

        2
  •  1
  •   jsh    14 年前

    至于用户的“讨厌的错误页面”,Django允许您自定义自己的500404和其他页面。一般信息:

    为了使用Http404异常 最重要的是,你应该创建一个 404时显示的模板 出现错误。此模板应 名为404.html并位于 模板树的顶层。

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

    另一个很好的方法,虽然不像tux21b的解决方案那样枯燥,但对于一次性解决方案来说可能更容易理解,可能是智能地捕捉错误。一种方法是这样做,甚至不用费心违反约束-一个简单的查询应该验证用户是否将要做一些非法的事情。

    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  
    

    (另一种方法是允许发生数据库冲突,然后捕获该错误并执行相同的操作。。。我的理论是,DB在查找时比处理异常时所承受的压力要小一些,但这取决于您喜欢怎么做)。

    接线盒