【问题标题】:Django: overriding single model field validationDjango:覆盖单个模型字段验证
【发布时间】:2013-02-08 08:05:21
【问题描述】:

我在一种情况下使用 django.db.models.fields.DecimalField,但它的验证错误非常糟糕。

就像,当用户输入 3,4 而不是 3.4 时,它会说 - '输入一个数字'。在某些国家,3,4 和 3.4 一样多。至少对于那些可能不精通计算机的人来说。

因此,出于这个原因,我试图覆盖此字段验证,以便我可以自己验证它。

我的问题是 - 在调用 modelforms clean_my_field() 之前,模型自己的验证工作并且它已经引发了错误。

所以我查了https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects

读完后我明白我可以做到

def full_clean(self):
    super(MyModel, self).full_clean(exclude = 'my_field')

my_field 将被排除在验证之外,我可以自己验证它

def clean(self)
    pass
    #how do i access cleaned data here anyway?
    #self.cleaned_data does not exist
    #is self.my_field the only way?

但是,可惜 - 它不起作用。 self.my_field 值是 clean() 方法中的旧值,clean_data 无处可寻。

这一切让我觉得我的方法是错误的。我想我可以编写自己的字段来扩展 django 的 DecimalField。我认为这种方法会起作用......有人可以为我解决这个问题 - 为什么它不起作用。如果它不起作用,为什么会在那里排除?顺便说一下 Django 版本 1.4.2。

艾伦

编辑:我挖得更深了。似乎即使我覆盖了所有模型清理方法并且根本不在其中使用 super - 字段仍然在某些时候被清理并且到那时已经引发了错误。

我想我会在这种情况下对 django.db.models.fields.DecimalField 做一些扩展。

关于为什么在 full_clean 方法中存在排除的答案仍然很好。如果它不起作用,为什么它在那里?

【问题讨论】:

  • 前段时间我经历了一大堆字段验证代码,并记得似乎有很多不同的方法可以做到这一点。我的猜测是 exclude 阻止了一种方法触发,但这不是您的情况下触发的方法。如果您还没有,我建议您逐步浏览源代码以查看发生了什么。无论如何,这是个好问题,我 +1。
  • 我刚刚创建了自己的 DecimalField 版本,并带有自己的验证,并在那里解决了我的问题。

标签: django django-models django-forms


【解决方案1】:

我知道这是一个老问题,但对于那些没有找到答案的问题,我所做的是在管理站点的 ModelAdmin 中添加 localize=True:

formfield_overrides = {
    models.DecimalField: {'localize': True},
}

这将使 FormField 语言环境感知,接受逗号作为小数分隔符(当然取决于当前语言环境)。它还将显示它已本地化。

https://docs.djangoproject.com/en/dev/topics/i18n/formatting/#locale-aware-input-in-forms

如果您的目标是单个 DecimalField,或者您正在编写自定义表单或模型表单,只需按照 URL 上的说明进行操作即可。

【讨论】:

    【解决方案2】:
    def views_name(request):
        ......
        field = dec_num(form.cleaned-data['....'])
        .........
    
        return render(request, 'page.html', {.....})
    
    
    def dec_num(value):
        return value.replace(",",".")
    

    【讨论】:

    • 这可能甚至几乎可以工作。可能不是你写的方式,而是像 dict = request.POST.copy() 这样的方式。然后像使用 dec_num() 一样检查值。然后将 dict 传递给 form 而不是 request.POST。但是视图听起来像是表单/字段验证的坏地方
    猜你喜欢
    • 1970-01-01
    • 2015-08-06
    • 2014-05-03
    • 1970-01-01
    • 2010-12-10
    • 2012-05-10
    • 1970-01-01
    • 2019-12-24
    相关资源
    最近更新 更多