2012-03-22 24 views
8

假设我有一个address表,它有一个postal_code字段 - ModelChoiceField不允许我使用除PK以外的其他内容来验证存在是否正确?将要走什么路?正常输入和使用clean_*()Django ModelChoiceField - 使用id以外的内容吗?

+0

依赖于关系模型是如何设置的,默认情况下它与'postal_code'模型'primary_key'。你可以给你更多的细节,比如你的'地址'和相关的'postal_code'模型。 'ModelChoiceField'默认创建一个下拉菜单,并带有作为相关模型的现有实例的选项。 – Pannu 2012-03-22 17:23:49

回答

0

ModelChoiceFields旨在用于选择现有模型实例。这几乎总是由某种形式的选择字段来表示。

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

对于大多数情况下,postal_code应该只是一个CharField,在这种情况下,如果要验证该值是否有效,可以使用choices属性和有效邮政编码列表。请记住,手工维护有效的邮政编码清单是一个巨大的麻烦。

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

1

如果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 
20

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

例如:

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

完美地工作。 – user240515 2012-08-07 17:47:43

+2

注意,在1.4(还没有尝试过1.5,对不起)与'instance'参数一起使用时会被破坏,因为'model_to_dict'强制使用PK(实际上是'value_for_object')。要解决此问题,必须先执行'YourForm(...,instance = foo,initial = {“bar”:foo.bar.slug})''。详情请参阅'BaseModelForm .__ init__'实现。 – drdaeman 2013-03-12 19:54:25

+1

@drdaeman [确实](https://code.djangoproject.com/ticket/20202) – valtron 2013-04-04 20:34:10