最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically update Django form field options using Ajax to GET new queryset - Stack Overflow

programmeradmin0浏览0评论

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 ments.

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.

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 ments.

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.

Share Improve this question edited Jun 22, 2017 at 12:58 Luce Rawds asked May 12, 2017 at 13:39 Luce RawdsLuce Rawds 911 silver badge4 bronze badges 1
  • 1 You cannot do this from the server side. Create an API for this using django-rest-framework or similar and then use javascriping to implement the form on the client side – dkarchmer Commented May 12, 2017 at 13:45
Add a ment  | 

2 Answers 2

Reset to default 3

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

Use ajax to send the category and retrieve subcategory elements.

For the category, send it via get request, and using the orm return the subcategories in a json format which you can show using jQuery.

发布评论

评论列表(0)

  1. 暂无评论