1

I am trying to create a choicefield in a form which only contains those fields which relate to a previously selected option. So far on the site a user can select a parent option ( I Call discipline) and then submit at which time they are ask to select from a set of fields which are a subset of the selected discipline. Currently the pages all work and render except that on the second page I also get the same 6 results regardless of which discipline I select. I ran a print command and can see the objects.filter are returning the correct results but those results are not appearing in the drop down menu. I am stumped.... any suggestions?

I have tried a number of online tutorials and checked several questions in stack exchange but nothing matches my issue. I am really confused how

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

returns the correct results yet:

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

only ever shows the same 6 results.

My Models are:

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    

My Views are:

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})

My forms are:

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']

And lastly my template file is:

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

I get no error messages, everything seems to work, the issues is that I only every get the same 6 results in the second dropdown, even though the print line displays the correct queryset in the console. Any suggestions are appreciated.

Gasanov
  • 2,839
  • 1
  • 9
  • 21
  • I have been continuing to try and sort out what is going on, still no luck. I tried using choices attribute instead of queryset as describted in this article: https://stackoverflow.com/questions/16056045/django-modelform-choicefield-not-displaying-instance-data but no luck. I also tried setting the results of the queryset to a variable which I then printed to the screen to confirm content and that content was correct. I then set the .queryset = to this variable and it still display ONLY the results from the one table entry. – Robert McLean May 17 '19 at 03:36
  • To test the form I added if request.method == 'POST': print(request.POST['field_name']) It is outputting the selected option so the page works, it is just that the option in the selection box are wrong. – Robert McLean May 17 '19 at 03:36

1 Answers1

0

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})
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • I made your suggested changes (self.fields['field_name'].queryset = Field.objects.filter(discipline_Main=disciplineID)), thank you. Unfortunately the problem still persists. No matter what I select the second page only every has the same six options in the selection box. Still rather confused. Do you have any other suggestions? – Robert McLean May 16 '19 at 17:25