简体   繁体   English

Django:如何覆盖 unique_together 错误消息?

[英]Django: How to override unique_together error message?

In a model's Meta class, I define a unique_together.在模型的 Meta 类中,我定义了一个 unique_together。 I have a ModelForm based on this model.我有一个基于这个模型的 ModelForm。 When I call is_valid on this ModelForm, an error will automatically raised if unique_together validation fails.当我在此 ModelForm 上调用 is_valid 时,如果 unique_together 验证失败,则会自动引发错误。 That's all good.这一切都很好。

Now my problem is that I'm not satisfied with the default unique_together error message.现在我的问题是我对默认的 unique_together 错误消息不满意。 I want to override it.我想覆盖它。 How can I do that?我该怎么做? For a field related error, I can easily do that by setting error_messages on the field parameters.对于与字段相关的错误,我可以通过在字段参数上设置 error_messages 来轻松做到这一点。 But unique_together is a non field error.但 unique_together 是非字段错误。 How can I override a non field error message?如何覆盖非字段错误消息?

You can do this since Django 1.7你可以做这个,因为Django的1.7

from django.forms import ModelForm
from django.core.exceptions import NON_FIELD_ERRORS

class ArticleForm(ModelForm):
    class Meta:
        error_messages = {
            NON_FIELD_ERRORS: {
                'unique_together': "%(model_name)s's %(field_labels)s are not unique.",
            }
        }

Update 2016/10/20 : See jifeng-yin 's even nicer answer below for Django >= 1.7 2016 年 10 月 20 日更新:请参阅下面 jifeng-yin对 Django >= 1.7 的更好回答

The nicest way to override these error messages might be to override the unique_error_message method on your model.覆盖这些错误消息的最好方法可能是覆盖模型上的unique_error_message方法。 Django calls this method to get the error message whenever it encounters a uniqueness issue during validation.每当在验证过程中遇到唯一性问题时,Django 都会调用此方法以获取错误消息。

You can just handle the specific case you want and let all other cases be handled by Django as usual:你可以只处理你想要的特定情况,让 Django 像往常一样处理所有其他情况:

def unique_error_message(self, model_class, unique_check):
    if model_class == type(self) and unique_check == ('field1', 'field2'):
        return 'My custom error message'
    else:
        return super(Project, self).unique_error_message(model_class, unique_check)

For DRF serializers you can use this对于 DRF 序列化程序,您可以使用它

from rest_framework import serializers


class SomeSerializer(serializers.ModelSerializer):


    class Meta:
        model = Some
        validators = [
            serializers.UniqueTogetherValidator(
                queryset=model.objects.all(),
                fields=('field1', 'field2'),
                message="Some custom message."
            )
        ]

Here is the original source .这是原始来源

After a quick check, it seems that unique_together validation errors are hard-coded deep in django.db.models.Model.unique_error_message :快速检查后,似乎unique_together验证错误是硬编码在django.db.models.Model.unique_error_message深处:

def unique_error_message(self, model_class, unique_check):
    opts = model_class._meta
    model_name = capfirst(opts.verbose_name)

    # A unique field
    if len(unique_check) == 1:
        field_name = unique_check[0]
        field_label = capfirst(opts.get_field(field_name).verbose_name)
        # Insert the error into the error dict, very sneaky
        return _(u"%(model_name)s with this %(field_label)s already exists.") %  {
            'model_name': unicode(model_name),
            'field_label': unicode(field_label)
        }
    # unique_together
    else:
        field_labels = map(lambda f: capfirst(opts.get_field(f).verbose_name), unique_check)
        field_labels = get_text_list(field_labels, _('and'))
        return _(u"%(model_name)s with this %(field_label)s already exists.") %  {
            'model_name': unicode(model_name),
            'field_label': unicode(field_labels)
        }

So maybe you should try to override this method from your model, to insert your own message !?所以也许你应该尝试从你的模型中覆盖这个方法,插入你自己的消息!?

However, I haven't tried, and it seems a rather brutal solution !但是,我没有尝试过,这似乎是一个相当残酷的解决方案! But if you don't have something better, you might try...但是如果你没有更好的东西,你可以尝试......

Notice: A lot had changed in Django since this answer.注意:自从这个答案以来,Django 发生了很多变化。 So better check other answers...所以最好检查其他答案......

If what sebpiq is true( since i do not check source code), then there is one possible solution you can do, but it is the hard way...如果 sebpiq 是真的(因为我不检查源代码),那么您可以执行一种可能的解决方案,但这是一种艰难的方法......

You can define a validation rule in your form, as it described here您可以在表单中定义验证规则, 如此处所述

You can see examples of validation with more than one field, so by using this method, you can define a unique together check before standard django unique check executed...您可以看到包含多个字段的验证示例,因此通过使用此方法,您可以在执行标准 django 唯一检查之前定义唯一的一起检查...

Or the worst one, you can do a validation in your view before you try to save the objects...或者最糟糕的是,您可以在尝试保存对象之前在视图中进行验证...

You might take a look at overriding django/db/models/base.py:Model._perform_unique_checks() in your model.您可能会在模型中查看覆盖django/db/models/base.py:Model._perform_unique_checks()

In that method you can get the "original" errors:在该方法中,您可以获得“原始”错误:

    errors = super(MyModel, self)._perform_unique_checks(unique_checks)

-- then modify and return them upwards. -- 然后修改并向上返回它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM