Трудности загрузки частичного для зависимого выпадающего списка в шаблоне Django
Я пытаюсь реализовать зависимый выпадающий список между странами и городами, но документ, отвечающий за загрузку городов, не загружается. Я пытаюсь решить эту проблему уже 3 дня и ничего не получается. С базой данных проблем нет, так как я тестировал ее с неajax запросами. И это не проблема базы данных, потому что вся часть не загружается.
Наиболее вероятной причиной проблемы является то, что я взял за основу некоторый код из онлайн-учебника, который, вероятно, использует старые версии либо JQuery, либо Django. Но, вот код
Models.py
from django.db import models
class Country(models.Model):
class Meta:
db_table = 'countries'
name = models.CharField(max_length=300)
def __str__(self):
return self.name
class City(models.Model):
class Meta:
db_table = 'cities'
name = models.CharField(max_length=300)
state_id = models.BigIntegerField(null=True)
country = models.ForeignKey(Country, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Person(models.Model):
class Meta:
db_table = 'people'
name = models.CharField(max_length=300)
birthdate = models.DateField(null=True, blank=True)
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True)
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
Forms.py
from django import forms
from .models import Person, City
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ('name', 'birthdate', 'country', 'city')
""" right now we are overriding the default init method, and setting the queryset of the city field to an empty list of cities: """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['city'].queryset = City.objects.none()
if 'country' in self.data:
try:
country_id = int(self.data.get('country'))
self.fields['city'].queryset = City.objects.filter(country_id=country_id).order_by('name')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and fallback to empty City queryset
elif self.instance.pk:
pass
# self.fields['city'].queryset = self.instance.country.city_set.order_by('name')
urls.py из проекта
from django.urls import path, include
from django.views.generic import RedirectView
from django.conf.urls.i18n import i18n_patterns
import debug_toolbar
from django.conf import settings
urlpatterns = i18n_patterns(
path('', RedirectView.as_view(pattern_name='person_changelist'), name='home'),
path('countries/', include('countries.urls')),
path('__debug__/', include(debug_toolbar.urls)),
prefix_default_language=False
)
urls.py из приложения Coutries
from django.urls import include, path
from . import views
urlpatterns = [
path('', views.PersonListView.as_view(), name='person_changelist'),
path('add/', views.PersonCreateView.as_view(), name='person_add'),
path('<int:pk>/', views.PersonUpdateView.as_view(), name='person_change'),
path('ajax/load-cities/', views.load_cities, name='ajax_load_cities'),
path('man/load-cities/<int:pk>/', views.load_cities2, name='man_load_cities'),
]
Views.py
from django.shortcuts import render
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy
from .models import Person, City
from .forms import PersonForm
class PersonListView(ListView):
model = Person
context_object_name = 'people'
class PersonCreateView(CreateView):
model = Person
form_class = PersonForm
success_url = reverse_lazy('person_changelist')
class PersonUpdateView(UpdateView):
model = Person
form_class = PersonForm
success_url = reverse_lazy('person_changelist')
def load_cities(request):
country_id = request.GET.get('country')
cities = City.objects.filter(country_id=country_id).order_by('name')
return render(request, 'countries/city_dropdown_list_options.html', {'cities': cities})
def load_cities2(request, pk):
# country_id = request.GET.get('country')
country_id = pk
cities = City.objects.filter(country_id=country_id).order_by('name')
return render(request, 'countries/city_dropdown_list_options.html', {'cities': cities})
person_form.html
{% extends 'base.html' %}
{% load i18n %}
{# NOTE: templates must be defined into a folder having the same name than
the application, like here countries/person_list.html, because Django
automatically search from <template_folder_in_app_folder/app_name/template.html #}
{% block content %}
<h2>{% trans "Person Form" %}</h2>
<form method="post" novalidate>
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<button type="submit">Save</button>
<a href="{% url 'person_changelist' %}">Nevermind</a>
</form>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$("#id_country").change(function (){
// getting the url of the load_cities view
var url = $("#personForm").attr("data-cities-url");
// get the selected country id from the html element
var countryId = $(this).val();
$.ajax({
url: url,
data: {
// adding the countryId to GET parameters
'country': countryId
},
// data is the return value of the 'load_cities' function
success: function(data){
// replace the contents of the city input with the data
// that came from the server.
// console.log($("#id_city").html(data));
$("#id_city").html(data);
}
});
});
</script>
{% endblock %}
И, наконец, шаблон, который не загружается: city_dropdown_list_options.html
<option value="">----city list----</option>
<!-- THIS DOCUMENT DOESN'T LOAD EVEN IF I COMMENT THE FOLLOWING I DON'T EVEN GET THE <option value="">----city list----</option> -->
{% for city in cities %}
<option value="{{ city.pk }}">{{ city.name }}</option>
{% endfor %}
#>
Есть ли у вас какие-нибудь догадки?