【问题标题】:Django ModelChoiceField - use something other than id?Django ModelChoiceField - 使用 id 以外的东西?
【发布时间】:2012-04-07 07:06:39
【问题描述】:

假设我有一个address 表并且它有一个postal_code 字段——ModelChoiceField 不允许我使用PK 以外的其他东西来验证存在是否正确?要走的路是什么?正常输入并使用clean_*()?

【问题讨论】:

  • 取决于如何设置关系,默认情况下它使用postal_code 模型的primary_key。您能否提供更多详细信息,例如您的address 和相关的postal_code 模型。 ModelChoiceField 默认情况下会创建一个下拉菜单,其中包含作为相关模型的现有实例的选项。

标签: python django validation django-forms django-validation


【解决方案1】:

to_field_name 呢?我不确定它是否记录在任何地方,但您可以在ModelChoiceField 构造函数参数:https://github.com/django/django/blob/master/django/forms/models.py 之间轻松找到它。用于过滤字段查询集。

例如:

articles = ModelChoiceField(queryset=Articles.objects.all(),
        to_field_name='slug')

【讨论】:

  • 请注意,在 1.4 中(尚未尝试 1.5,抱歉)与 instance 参数一起使用时会损坏,因为 model_to_dict 强制使用 PK(实际上是 value_for_object)。要解决一个必须做YourForm(..., instance=foo, initial={"bar": foo.bar.slug})。有关详细信息,请参阅BaseModelForm.__init__ 实现。
  • 与此同时,Django 开发人员正在努力解决问题,我正在使用this quick-and-dirty monkey patch to make to_field_name work。只是想我会分享它,即使它是一个黑客。
  • 大家好,最近有人在使用 slug 而不是 ModelChoiceField 和 ChoiceField 的 id 时遇到问题吗?或者@drdaeman 提到的错误现在已修复?我正在使用 Django 1.5.5 顺便说一句,到目前为止我还没有遇到任何问题。
  • 适用于 Django-1.7.1
【解决方案2】:

ModelChoiceFields 旨在用于在现有模型实例的选项之间进行选择。这几乎总是最好用某种形式的 Select 字段来表示。

也就是说,您真的有一个从地址到邮政编码的 FK,正如您所暗示的那样。您在 PostalCode 表上存储了什么来证明每个地址相关查询都需要加入额外的表?

在大多数情况下,postal_code 应该只是一个 CharField,在这种情况下,如果您想验证该值是否有效,您可以使用带有有效邮政编码列表的 choices 属性。请记住,手动维护有效邮政编码列表非常麻烦。

如果您确实有一个 PostalCode 表并认为这是一个好主意(在某些情况下可能是这样),您可能需要考虑实际使用 postal_code 作为主键,而不是默认的自动增量,因为它必须是唯一的,从而使您的数据更易于导出,并解决您的验证问题。

【讨论】:

    【解决方案3】:

    如果postal_code 是包含有效邮政编码的 PostalCode 模型的外键,我会使用 CharField,然后按照您的建议进行清理。我的干净方法如下所示:

    def clean_postal_code(self):
        try:
            code = PostalCode.objects.get(code_field=self.data['postal_code'])
        except:
            raise forms.ValidationError("Please enter a valid postal code")
        return code
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 2015-06-23
      相关资源
      最近更新 更多