Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Admin, how to populate select options depending on another select

My scenario:

I'm having three tables, Category, Subcategory, Products. While inserting new product, there are two select boxes

1)1st select is for Category (its working)

2) 2nd is for Subcategory, which should be relevant to the 1st select. Needs to fetch the data from subcategory table.

Subcategory table has category id as a foreign key. I am a beginner, please somebody help.

like image 545
Binayak Avatar asked Dec 16 '17 06:12

Binayak


2 Answers

You will have to use some JS library I prefer JQuery.

For filling this subcategory field, you have to create a view which will respond with json data.

from django.http import HttpResponse
import json

def get_subcategory(request): 
    id = request.GET.get('id','') 
    result = list(Subcategory.objects.filter(category_id=int(id)).values('id', 'name')) 
    return HttpResponse(json.dumps(result), content_type="application/json") 

At urls.py you need to add a pattern to reach the view:

url(r'^/getSubcategory/$', views.get_subcategory) 

Now you have to override change_from.html of django admin for your product app to add some JS code to do the magic.

your_project
     |-- your_project/
     |-- myapp/
     |-- templates/
          |-- admin/
              |-- myapp/
                  |-- change_form.html  # do not misspell this

Note: The location of this file is not important. You can put it inside your app and it will still work. As long as its location can be discovered by django. What's more important is the name of the HTML file has to be the same as the original HTML file name provided by django.

In your change_form.html, write somethings like this:

{% extends "admin/change_form.html" %} 

{% block extrahead %}
    {{ block.super }} 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
    <script type="text/javascript" charset="utf-8"> 
        $(function(){ 
            // inspect html to check id of category select dropdown.
            $(document).on('change', "select#id_category", function(){ 
                $.getJSON("/getSubcategory/",{id: $(this).val()}, function(j){ 
                     var options = '<option value="">---------</option>'; 
                     for (var i = 0; i < j.length; i++) { 
                         options += '<option value="' + j[i].id + '">' + j[i].name + '</option>'; 
                     } 
                     // inspect html to check id of subcategory select dropdown.
                     $("select#id_subcategory").html(options); 
                 }); 
             }); 
         }); 
    </script>
{% endblock %} 
# Create a JS file and put this second script tag in it, that way will be easier to maintain your template.
like image 63
Satendra Avatar answered Oct 22 '22 18:10

Satendra


url: path('features/',views.get_features,name='features'),
views: def get_features(request):
    id = request.GET.get('id','')
    cat = Category.objects.get(pk=id) 
    result = list(Feature.objects.filter(category=cat).values('id', 'name')) 
    print(result)
    return HttpResponse(json.dumps(result), content_type="application/json") 

javascript:             $(function(){ 
        // inspect html to check id of category select dropdown.
        $(document).on('change', "select#category_select_m1", function(){ 
            $.getJSON("features/",{id: $(this).val()}, function(j){ 
                 var options = '<option value="" disabled selected>Choose your feature</option>'; 
                 console.log(j);
                 for (var i = 0; i < j.length; i++) { 
                     options += '<option value="' + j[i].id + '">' + j[i].name + '</option>'; 
                 } 
                 // inspect html to check id of subcategory select dropdown.
                 $("select#feature_select_m1").html(options); 
             }); 
         }); 
     }); 

Updated for django 2.1 but not working and thanks to Satendra. I can not comment above thats why submitted my problem as answer

like image 20
Mobasshir Bhuiya Avatar answered Oct 22 '22 19:10

Mobasshir Bhuiya