首页 > 解决方案 > 无论输入如何,Django ModelChoiceField 查询集都会返回相同的结果

问题描述

我正在尝试以仅包含与先前选择的选项相关的那些字段的形式创建一个选择字段。到目前为止,在网站上,用户可以选择一个父选项(我调用学科)然后提交,此时他们被要求从一组字段中进行选择,这些字段是所选学科的子集。目前,这些页面都可以正常工作并呈现,除了在第二页上,无论我选择哪个学科,我都会得到相同的 6 个结果。我运行了一个打印命令,可以看到 objects.filter 返回正确的结果,但这些结果没有出现在下拉菜单中。我很难过....有什么建议吗?

我已经尝试了许多在线教程并检查了堆栈交换中的几个问题,但没有一个符合我的问题。我真的很困惑如何

fieldOptions = Field.objects.filter(discipline_Main=discipline)
print("The available fields are: %s" % fieldOptions) 

返回正确的结果:

field_name = forms.ModelChoiceField(queryset=Field.objects.filter(discipline_Main=disciplineID)) 

只显示相同的 6 个结果。

我的模型是:

class Discipline(models.Model):
    #This is the top level category ie: Math, physics, chemistry, biology, history, english, etc
    discipline_name = models.CharField(max_length=50)
    description_text = models.CharField(max_length=200)
    discipline_create_date = models.DateTimeField(default=datetime.now, blank=True)

    def __str__(self):
        return self.discipline_name

class Field(models.Model):
    #This is the level below discipline, example for math would be:
    #Foundations, number systems, logics, etc
    field_name = models.CharField(max_length=50)
    description_text = models.CharField(max_length=200)
    discipline_Main = models.ForeignKey(Discipline, on_delete=models.PROTECT, related_name='discipline_Main', null=True)
    create_date = models.DateTimeField('Field Creation Date', default=datetime.now, blank=True)

    def __str__(self):
        return self.field_name    

我的观点是:

def pullDiscipline(request):
    if request.method == 'POST':
        print("If statement has run")
        form = forms.DisciplineForm(request.POST)

        if form.is_valid():
            print("Form was valid, what now?")
            print(request.POST['discipline_name'])
            discipline = Discipline.objects.get(discipline_name=request.POST['discipline_name'])
            print("The current discipline is: %s" % discipline)
            context = discipline.id
            print("The id for chemistry is: %s" % context)
            return redirect('/assessment/pullField/%s' % context)
    else:
        print("Else statement run")
        form = forms.DisciplineForm(request.POST)
    return render(request, "assessment/pullDiscipline.html", {'form' : form})


def pullField(request, pk):
    disciplineID = pk
    form = forms.FieldForm(disciplineID, request.POST)
    return render(request, "assessment/pullField.html", {'form' : form})

我的表格是:

class FieldForm(ModelForm):

    def __init__(self,disciplineID,*args,**kwargs):
        print("Field form is called")
        print("THe disciplineID is: %s" % disciplineID)
        discipline = Discipline.objects.get(id=disciplineID)
        print("The name of the discipline is: %s" % discipline)
        fieldOptions = Field.objects.filter(discipline_Main=discipline)
        print("The available fields are: %s" % fieldOptions)
        #Fetches only requested options from Field model to populate the drop down
        super(FieldForm,self).__init__(*args, **kwargs)
        field_name = forms.ModelChoiceField(queryset=Field.objects.filter(discipline_Main=disciplineID))

    class Meta:
        model = Field
        fields = ['field_name']

最后我的模板文件是:

<form id="pullField" method="POST" >
{% csrf_token %}
{{form.field_name}}
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>

我没有收到错误消息,一切似乎都正常,问题是我在第二个下拉列表中只得到相同的 6 个结果,即使打印行在控制台中显示了正确的查询集。任何建议表示赞赏。

标签: djangodjango-querysetmodelformmodelchoicefield

解决方案


Change this line in your Form:

field_name = forms.ModelChoiceField(queryset=Field.objects.filter(discipline_Main=disciplineID))

To:

self.fields['field_name'].queryset = Field.objects.filter(discipline_Main=disciplineID)

Also, please don't pass request.POST as argument with your Form instance initiation when you are not making POST request. For example:

def pullField(request, pk):  # Please use Pascal Case when defining ClassName
    disciplineID = pk
    form = forms.FieldForm(disciplineID)  # removed request.POST because its a GET request
    return render(request, "assessment/pullField.html", {'form' : form})

def pullDiscipline(request):  # Please use Pascal Case when defining ClassName
    if request.method == 'POST':
        # POST related codes
    else:
        form = forms.DisciplineForm()  # removed request.POST
    return render(request, "assessment/pullDiscipline.html", {'form' : form})

推荐阅读