A path (perhaps the most obvious) is to use javascript, in the first select you arrow an onchange that calls a function to "popular" the second select.
Have a demo here that fits your question perfectly, just make the appropriate adjustments. Do not be intimidated by the code in the javascript section (bottom). The guy created arrays with several countries / states of the world, so it was so extensive, go straight down the two functions (populateStates and populateCountries).
Basically, he did the following, calls these two functions when the page is loaded and populates the two selects (as the country has not yet been chosen, the states select is empty), on that occasion, in the populateCountries function it changes the select onchange from countries to call the function that populates states (populateStates) by sending objects to it.
Try to adapt, if you can not, post here the problem.
Edited from 03/20/2017 (from here)
Ok, As combined (in the comments of this answer), I spent my Saturday to create my own version to try to answer what was requested. The explanation here is only to elucidate how the process was to get the database, go to the django template and, finally, deliver it to JS. The project (in Django), complete and functional can be downloaded in this repo github .
In the example we will use a vehicle register in a fleet (see that I did not take care of recording the data in the bank, I focused only on what was requested in the question). There are two main demo models, one for Brands and one for Car Models.
models.py
from django.db import models
import json
class Brand(models.Model):
company_name = models.CharField(max_length=100)
def __str__(self):
return self.company_name
class Car(models.Model):
brand = models.ForeignKey(Brand)
name = models.CharField(max_length=100)
def __str__(self):
return {'name': self.name, 'brand': self.brand.company_name}
It is important to note that an artifice was used in the __str__ function of the Car model, so that the call to objects.all () returns a dictionary with the name and brand of the models.
With the models ready, let's take a look at what the main function is to make the data available to the template and, consequently, to JS.
import json
from django.shortcuts import render
from .models import Brand, Car
def regcar(request):
brands = Brand.objects.all()
cars = Car.objects.all()
dcars = {}
for car in cars:
brand = str(car.brand)
if brand in dcars:
dcars[brand].append(car.name)
else:
dcars[brand] = [car.name]
cars = json.dumps(dcars)
brands = json.dumps([str(b) for b in brands])
return render(request, 'core/regcar.html', {'brands': brands, 'cars': cars})
This view essentially makes the following:
- Select models from Brand objects and assign them to the variable
brands;
- Selects models of Car objects and assigns them to
variable cars;
- Converts the two variables to the JSON format;
- Renders the template regcar.
The template is very simple, it has only one div with the two selects, duly identified by ID. Although presented here separately, the JS script is included in the template, so it can be loaded along with it (it could be through a block, WYL.). In the loading process, the select labeled 'brand' will be loaded by a JS function.
{% load staticfiles %}
<!DOCTYPE html>
<html lang="pt-br">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script><linkhref="{% static "css/style.css" %}" rel="stylesheet">
<meta charset="UTF-8">
<title>Populating a Select with Django</title>
</head>
<body>
<h1>Populate one dropdown based on selection in another.</h1>
<p>Change the contents of dropdown Car based on the selection in dropdown Brand, using Django + Javascript:</p>
<div class="select-style">
<br />Brand:
<select required id="brand">
</select>
<br />
<br />Car:
<select id="car" >
</select>
</div>
</body>
</html>
The javascript code is loaded along with the template, at that time
two variables are created that receive the JSON values that were sent to the template by the view, see that it is enough to do the assignment normally, as if it were in python or in the template itself. In addition to the creation of these variables, the onchange event of the select of the tags (brand) is directed to the populateCar () function, where the select whose id = car (car models) is populated every time the select brand onchange is modified. Finally, the populateBrand () function is called to populate the select of the (brand) tags.
<script language="javascript">
$('#brand').change(function() {populateCar()});
var cars = {{ cars|safe }}
var brands = {{ brands|safe }}
populateBrand();
function populateBrand() {
$("#brand").empty();
$("#brand").append('<option value="" disabled selected>Select your option</option>');
$.each(brands, function(v) {
$('#brand')
.append($("<option></option>")
.attr("value", brands[v])
.text(brands[v]));
})
}
function populateCar(event) {
brand = $("#brand option:selected" ).text();
$("#car").empty();
$("#car").append('<option value="" disabled selected>Select your option</option>');
for (let [b, bcars] of Object.entries(cars)) {
if (b==brand) {
for (car in bcars) {
$('#car')
.append($("<option></option>")
.attr("value", bcars[car])
.text(bcars[car]));
}
}
}
}
</script>
Layout (Firefox)
Links:
ThissameissueinSTOen:
link
Complete project in Django:
link
Codepen version:
link
Fiddle Version:
link