Dynamically update Django form field options using Ajax to GET new queryset
ajax, django, django-forms, javascript
Solution
You can't do this from Django views side, ie, backend. You could try an ajax request for implementing this kind of requests, by sending a GET request to the server for populating the drop-down or whatever you are into.
For a simple example, you could refer here
How do I POST with jQuery/Ajax in Django?
EDIT
def update_subcategories(request):
category = request.GET.get('category', None)
sub_category = list(SubCategory.objects.filter(category__name__exact=category).values('name'))
return JsonResponse(dict(sub_category=sub_category))
Then in ajax response you could grab it like `response.data.sub_category`
Problem
I'm new to coding and django and I'm struggling to find the solution to the following problem having reviewed the answers I've found. Im creating a search form with multiple fields. When the user selects the first field `category` (and before hitting search) I would like to dynamically change the queryset for the second field `sub_category` such that only related values are shown. I have `models.py` as follows: ``` class Product(models.Model): category = models.ForeignKey("Category") sub_category = models.ForeignKey("SubCategory") class Category(models.Model): name = models.CharField(max_length=256) class SubCategory(models.Model): category = models.ForeignKey("Category") name = models.CharField(max_length=256) ``` And my `forms.py` includes: ``` class BasicSearchForm(forms.Form): category = forms.ModelChoiceField( label='Category', queryset=Category.objects.all(), to_field_name="name", empty_label=None, initial="Red") sub_category = forms.ModelMultipleChoiceField( required=False, label='Type', queryset= SubCategory.objects.all(), to_field_name="name", widget=forms.Select) ``` And my `views.py` includes: ``` def search(request): if request.method == 'POST': form = BasicSearchForm(request.POST) if form.is_valid(): category = form.cleaned_data['category'] sub_category = form.cleaned_data['sub_category'] return render(request, 'myapp/search.html', {'form': form}) else: form = BasicSearchForm() return render(request, 'myapp/search.html', {'form': form}) ``` And finally the search.html includes: ``` <form class="search-form" role="search" action="/search/" method="get"> {{ form }} <input type="submit" value="Search" /> </form> ``` I've played around with a few answers but nothing seems to work. I'd really appreciate some help. Thanks in advance! Update: Thanks for the feedback. As a result I updated the following: In my `urls.py`: ``` urlpatterns = [ url(r'^ajax/update_subcategories/$', views.update_subcategories, name='update_subcategories'), ``` And in my `views.py`: ``` def update_subcategories(request): category = request.GET.get('category', None) sub_category = list(SubCategory.objects.filter(category__name__exact=category).values('name')) return JsonResponse(sub_category, safe=False) ``` And I have this in my `myapp/search.html`: ``` {% block javascript %} <script> $("#id_category").change(function () { var category = $(this).val(); $.ajax({ url: '{% url "myapp:update_subcategories" %}', data: { 'category': category, }, success: function (response) { var new_options = response; alert(new_options[0].name); // works $('#id_sub_category').empty(); $.each(new_options, function(key, value) { $('#id_sub_category') .append($('<option>', { value : key }) .text(value.name)); }); } }); </script> {% endblock %} ``` Update: The sub_category options were showing as [object Object] until I changed value to value.name and it looks like it's working. I'll test it out and close unless there are any comments. Update: Im still having an issue with the browser back button. When a user clicks back the dropdown values have changed back to the original queryset rather than the updated version.