【问题标题】:Loading choices into choicefield - strange behavior将选择加载到选择字段中 - 奇怪的行为
【发布时间】:2017-04-21 05:44:12
【问题描述】:

我有一个带有选择字段的 django 表单,我在其中动态地将一些选项加载到该字段中:

class EntryForm(forms.Form):

    project = forms.ChoiceField()

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super(EntryForm, self).__init__( *args, **kwargs)

        CHOICES2=[]
        for x in Project.objects.all() :
            if user in x.users.all():
                CHOICES2.append((x.name,x.name)) 

        CHOICES1 = [(x.name,x.name) for x in Project.objects.all()]

        print CHOICES2==CHOICES1 #this is True in this case

        self.fields['project']=forms.ChoiceField(choices=CHOICES2)

使用 {{form.as_table}} 将表单加载到模板中。该表单不显示项目字段的下拉列表。 现在奇怪的是:如果我将最后一行更改为:

self.fields['project']=forms.ChoiceField(choices=CHOICES1)

它可以工作,尽管“==”比较的打印语句返回 True(列表故意相同 - 这只是为了测试)。我真的不知道这在技术上如何工作。

编辑 - 我的项目模型:

class Project(BaseModel):
    name  = models.CharField(max_length=80)
    users = models.ManyToManyField(User)

【问题讨论】:

  • 能否请您出示一下您的Project 模特?

标签: django


【解决方案1】:

您的名为project 的字段已经存在,无需像您一样构建另一个字段。最好只在现有字段上设置选项:

self.fields['project'].choices = CHOICES2

但也许你最好使用 ModelChoiceField:

project = ModelChoiceField(queryset=Project.objects.none())

然后在 init 中设置您想要的查询集,如下所示:

self.fields['project'].queryset=Project.objects.filter(users__in=[user])

..它应该为您提供与user 关联的所有项目的列表。

【讨论】:

    【解决方案2】:

    我认为您必须使用 queryset 参数,这是强制性的: https://docs.djangoproject.com/en/1.8/ref/forms/fields/#django.forms.ModelChoiceField.queryset

    ChoiceField 必须用 (queryset=None) 声明,并在 __init__ 方法中完成查询: https://docs.djangoproject.com/en/1.11/ref/forms/fields/#fields-which-handle-relationships

    问题可能与查询的执行顺序或非惰性查询的缓存有关。

    我同意 little_birdie:该领域已经存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-11
      • 2011-08-19
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 2013-01-29
      • 2014-05-28
      相关资源
      最近更新 更多