将选择加载到选择字段 - 奇怪的行为

时间:2017-04-21 05:44:12

标签: django

我有一个带有选择字段的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)

2 个答案:

答案 0 :(得分:0)

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

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

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

我同意little_birdie:该字段已经存在。

答案 1 :(得分:0)

您的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相关联的所有项目的列表。