I took almost unchanged guide from documentation there is my models.py
from django.db import models
class Country(models.Model):
name = models.CharField(max_length=255)
class City(models.Model):
name = models.CharField(max_length=255)
country = models.ForeignKey('Country', related_name="cities", on_delete=models.CASCADE)
class Address(models.Model):
country = models.ForeignKey('Country', on_delete=models.CASCADE)
city = models.ForeignKey('City', on_delete=models.CASCADE)
and have created ModelForm because simple Form from documentation guide is not fits for admin panel
class AddressForm(forms.ModelForm):
class Meta:
model = Address
fields = '__all__'
widgets = {
'country': ModelSelect2Widget(
model=Country,
search_fields=['name__icontains'],
),
'city': ModelSelect2Widget(
model=City,
search_fields=['name__icontains'],
dependent_fields={'country': 'country'},
max_results=500,
)
}
on the simple, not admin, page it works fine. I tried it just for testing. I really need only in admin panel. here is the template from docs
<!DOCTYPE html>
<html lang="en">
<head>
<title>Create Book</title>
{{ form.media.css }}
<style>
input, select {width: 100%}
</style>
</head>
<body>
<h1>Create a new Book</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
{{ form.media.js }}
</body>
</html>
and view class
class AddressCreateView(generic.CreateView):
model = models.Address
form_class = forms.AddressForm
success_url = "/"
template_name = 'address.html'
But in the admin panel the same form is not works. Selects does not containing any items and there is no search field shown there is also no requests sent to the server with I can see when interact with selects at the simple page
from django.contrib import admin
from .models import City, Country, Address
from .forms import AddressForm
@admin.register(Address)
class AddressAdmin(admin.ModelAdmin):
class Media:
js = (
'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js',
)
form = AddressForm
admin.site.register(City)
admin.site.register(Country)
This answer will save you a lot of time, DON'T use 'django_select2' to implement chained select fields in Django admin, instead use Django AutoComplete Light with Django-Hacker. where the DAL will be responsible to implement AJAX requests to retrieve the data for the chained Select2 field while Django-Hacker will save your time by customize default Django forms directly from anywhere in the api without need to create specific form to your admin class.
STEP1: pip the mentioned packages and then add below packages at top of
INSTALLED_APPSinsettings.pyfile:settings.py
Note: this will make sure to override the
jquery.init.jsscript provided by the admin, which sets up jQuery withnoConflict, making jQuery available indjango.jQueryonly and not$(global).STEP2: Make sure you have registered your api
urls.pyfile in the mainurls.pyfile of your Django project.STEP3: Create the view class that will be used to retrieve and update the data (using AJAX) for your chained Select2 field on the admin page, as shown in the below example.
views.py
STEP4: Finally you need to register this view inside your api
urls.pyfile and at the same time create a form field for your chained Select2 field.urls.py
That's all, we just made a chained Select2 field that depend on another field value and you can check it on Django admin page for the related model without need to make complex customize ajax file, customize your Django admin JavaScript or add cache server.. etc.