【问题标题】:Django model select choice, populated with fields from other model instancesDjango 模型选择选项,填充了来自其他模型实例的字段
【发布时间】:2014-03-20 10:36:53
【问题描述】:

假设我有一个模型 Car 具有字段品牌和模型所有者具有两个字段:name 和 car_brand,而后者应该是 Car 实例品牌之一。我需要有一个表单,其中向用户显示一个文本字段名称和一个下拉选择选项,其中填充了 Car 实例的所有品牌名称。我将如何实现这一目标?

这是我开始的代码。随意纠正。谢谢。

models.py

from django.db import models

class Car(models.Model):
    brand = models.CharField(max_length=20)

class Owner(models.Model):
    name = models.CharField(max_length=20)
    car_brand = models.ForeignKey(Car)

forms.py

from django.forms import ModelForm, TextInput, Select
from app.models import Owner

class OwnerForm(ModelForm):

    class Meta():
        model = Owner
        fields = ("name", "car_brand")
        widgets = {
            "name" : TextInput(attrs={"class" : "name"}),
            "car_brand" : Select(attrs={"class" : "car_brand"}),
        }

【问题讨论】:

  • 为什么要覆盖小部件?默认的模型表单会为您提供您想要的。
  • 我需要为每个字段定义类属性。
  • 另一个问题是:当models.ForeignKey(Car)没有指定选择什么字段时,它怎么知道从Car中选择“品牌”字段进行选择?

标签: python django-models django-forms foreign-keys


【解决方案1】:

您可能只需在您的 Car 模型上定义一个 __unicode__ 方法,我认为它应该可以正常工作。正如 Daniel 所提到的,由于您已经覆盖了小部件,因此表单可能会变得混乱。我可能是错的,但我认为 django 会自动在表单元素上呈现可用于样式目的的属性。也许您不需要覆盖小部件。如果没有,您可以明确指定表单字段:

class OwnerForm(ModelForm):
    car_brand = forms.ModelChoiceField(
        queryset=Car.objects.all(),
        widget=Select(attrs={'class': 'car_brand'}),
    )

    class Meta:
        model = Owner
        fields = ('name', 'car_brand')
        widgets = {
            'name': TextInput(attrs={'class': 'name'})
        }

作为旁注,您是否有任何理由没有 CarBrand 模型和与 Car 模型相关的外键字段?这将是一种更规范化的数据建模方法。

【讨论】:

  • 谢谢。为什么我需要另一个模型在中间?现在我的关系是 Owner-Car。使用附加模型,我将拥有 Owner-Car-CarBrand。这样做有什么好处?
  • 优点是您不会在 Car.brand 字段中重复数据。使用这种方式定义的 Car 模型,人们可以在该字段中放置任何他们想要的东西,你最终可能会得到“Acura”、“acura”、“acira”、“acra”等。你需要添加一堆程序逻辑来纠正或跟踪同一品牌拼写的不同变化。如果您有一个单独的 CarBrand 模型,则更容易纠正错别字或类似错误,如果您在 CarBrand.name 字段上设置唯一约束,则实际上不可能复制数据。
  • 顺便说一句,如果你觉得我的回复够好,请不要忘记将我的回复标记为答案。
  • 如果你有兴趣,这里有一篇关于数据库规范化的文章:en.wikipedia.org/wiki/Database_normalization
  • 我很确定您会通过在您的 Car 模型上定义 __unicode__ 方法来表明这一点。 ModelChoiceField 应该通过对指定查询集中的每个 obj 执行类似 unicode(obj) 的操作来构建选项名称。更多信息在这里:docs.djangoproject.com/en/dev/ref/models/instances/…
猜你喜欢
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多