Using Ajax with forms.CheckboxSelectMultiple and a dependent dropdown

I have a dropdown that when a user selects something the form brings up dependant options for a ManyToManyField and this works fine using ajax and the code below:

#forms.py
class WeighbridgeForm(ModelForm): 
   
    class Meta:
        model = Weighbridge
     
    def __init__(self, *args, **kwargs):
        super(WeighbridgeForm, self).__init__(*args, **kwargs)
        self.fields['variety'].queryset = Variety.objects.none()
        
        if 'commodity' in self.data: 
            try:
                commodity = self.data.get('commodity')
                self.fields['variety'].queryset = Variety.objects.filter(commodity=commodity)
                  
                
            except (ValueError, TypeError): 
                pass

        elif self.instance.pk:
            self.fields['variety'].queryset = self.instance.commodity.variety_set

#views.py
def load_varieties(request): 
    
    commodity = request.GET.get('commodity')
    varieties = Variety.objects.filter(commodity=commodity)
    return render(request, 'stocks/variety_filter.html', context={'varieties':varieties})
<!--html template ajax section-->
<option value="">---------</option>
{% for variety in varieties %}
<option value="{{ variety.pk }}">{{ variety.variety_name }}</option>
{% endfor %}
<!--script for the ajax in the template for the form-->
<script>
    $("#id_commodity").change(function () {
    var url = $("#weighbridgeForm").attr("data-varieties-url");  // get the url of the `load_varieties` view
      var commodity = $(this).val();  // get the selected commodity ID from the HTML input

      $.ajax({                       // initialize an AJAX request
        url: url,                    // set the url of the request (= localhost:8000/hr/ajax/load-varieties/)
        data: {
        'commodity': commodity      // add the commodity id to the GET parameters
        },
        
        success: function (data) {   // `data` is the return of the `load_varieties` view function
        $("#id_variety").html(data);  // replace the contents of the variety input with the data that came from the server
        }
      });
    
    });
  </script>

This all works fine but I want it to be a multiple selecting checkbox widget. When I add this to the forms.py file:

 widgets = {
            'variety': forms.CheckboxSelectMultiple
        }

nothing is rendered for variety. I have tried changing the html template for the ajax page but to no avail. What format is django expecting the data in for a CheckboxSelectMultiple widget so that it will render the options properly as a checkbox instead of a list? I understand what is wrong but I don’t know how to fix it…

Any further questions or if my problem isn’t clear please let me know and thanks in advance.

I think that you must use (ModelMultipleChoiceField) as Django Docs stated

The next tutorial is very useful Django Forms for Many-to-Many Fields

Hope you find what you are looking for

Thanks - I have read through these. The examples provided uses the user to filter the queryset not an input the user puts into the screen - I don’t want to direct to a new url for each filter choice hence why I am using ajax.

When I changed widgets = { 'variety': forms.CheckboxSelectMultiple }
to

variety = forms.ModelMultipleChoiceField( queryset=None, widget=forms.CheckboxSelectMultiple )

This renders the checkboxes fine without using the ajax filter on commodity. When I try using ajax it just renders a blank box. This makes me think the problem is with my ajax code somehow (not an expert on ajax). Any ideas on this?

Thanks

You should write all your form fields in data atribute as ('field_name': $('#field_id').val())

Take a look at this Question