【问题标题】:Django Modelchoicefield values in different format不同格式的 Django Modelchoicefield 值
【发布时间】:2014-10-11 22:25:00
【问题描述】:

我已经使用 ModelChoiceField 创建了表单并从数据库模型中加载了值。 我正在使用下面的代码来创建表单

class MetamodForm(forms.Form):
     metamodule_name = forms.ModelChoiceField(queryset=Metamodule.objects.all().values("name").distinct(),empty_label='Pick a Meta module')

但我得到的输出格式为

{'name': u'CCD infra'}
{'name': u'dependf'}
{'name': u'BAR weste'}

我不确定为什么会得到上述输出。请给我一个解决方案。

【问题讨论】:

  • 你期望输出什么?
  • 只是我在数据库模型中的数据。 CCD 基础, 依赖, BAR 西
  • @crhodes:当我使用 Metamodule.objects.all() 时,我得到了预期的正确输出。但是当我使用 values('name') 时,我得到了那种输出。
  • .values() 返回一个 ValuesQuerySet,它的行为可能与您在此处所期望的不同。 docs.djangoproject.com/en/1.6/ref/models/querysets/…
  • @scoopseven:好的。是否有可能在不使用 values() 或 values_list() 的情况下获得不同的对象?

标签: django model


【解决方案1】:

在此示例中,由于您使用的是 .all(),因此您不需要使用 distinct。

https://docs.djangoproject.com/en/1.6/ref/models/querysets/#django.db.models.query.QuerySet.values

Values 返回的不是 QuerySet (a ValuesQuerySet ),这就是为什么你没有得到你想要的格式。

解决方案是不使用查询集上的 .values 和 .distinct 调用。

替换

forms.ModelChoiceField(
    queryset=Metamodule.objects.all().values("name").distinct(),
    empty_label='Pick a Meta module')

forms.ModelChoiceField(
    queryset=Metamodule.objects.all(),
    empty_label='Pick a Meta module')

我猜您正在尝试让模型表单显示“名称”字段作为选项。您可以编写 Metamodule 的 unicode 方法来影响它在表单上的显示方式,或者使用 ModelChoiceField 的 label_from_instance。

https://docs.djangoproject.com/en/1.6/ref/forms/fields/#django.forms.ModelChoiceField

【讨论】:

    【解决方案2】:

    仅在 PostgreSQL 上,您可以传递位置参数 (*fields) 以指定应应用 DISTINCT 的字段名称。

    所以如果你使用的是 PostgreSQL,你可以这样做:

    Metamodule.objects.distinct('name)
    

    如果不是,这可能是一个混搭。我相信有人会用做同样事情的单线来更新它。

    metamodules = Metamodule.objects.all()
    metamodule_name_list = []
    metamodule_id_list = []
    for metamodule in metamodules:
        if metamodule.name not in metamodule_name_list:
            metamodule_name_list.append(metamodule.name)
            metamodule_id_list.append(metamodule.id)
    distinct_metamodules_by_name = Metamodule.objects.filter(id__in=metamodule_id_list)
    
    forms.ModelChoiceField(
        queryset=distinct_metamodules_by_name,
        empty_label='Pick a Meta module')
    

    我不知道您为什么要这样做,但请注意,虽然您会在下拉列表中看到一个独特的“名称”, 在您的视图中处理时,您可能无法获得您实际正在寻找的 id/对象。

    【讨论】:

      猜你喜欢
      • 2016-06-12
      • 2021-07-24
      • 2010-11-23
      • 2011-10-06
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      相关资源
      最近更新 更多