Как реализовать 4-сторонний зависимый выпадающий список в Django?

Я пытаюсь сделать 4-зависимый выпадающий список с помощью Django. Я следую этому примеру кода с 3 выпадающими списками https://github.com/masbhanoman/django_3way_chained_dropdown_list

но я получаю ошибку. Вот мой код:

models.py

from django.db import models


class Country(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class City(models.Model):
    country = models.ForeignKey(Country, on_delete=models.CASCADE)
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class Vanue(models.Model):
    name = models.CharField(max_length=10)
    city = models.ForeignKey(City, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

class Area(models.Model):
    name = models.CharField(max_length=10)
    vanue = models.ForeignKey(Vanue, on_delete=models.CASCADE)

    def __str__(self):
        return self.name


class Person(models.Model):
    name = models.CharField(max_length=100)
    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)
    vanue = models.ForeignKey(Vanue, on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return self.name

forms.py

from django import forms
from .models import Person, City, Vanue, Area

class PersonForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ('name', 'birthdate', 'country', 'city', 'vanue', 'area')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['city'].queryset = City.objects.none()

        
        #city
        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:
            self.fields['city'].queryset = self.instance.country.city_set.order_by('name')
        #vanue
        self.fields['vanue'].queryset = City.objects.none()
        if 'city' in self.data:
            try:
                city_id = int(self.data.get('city'))
                self.fields['vanue'].queryset = Vanue.objects.filter(city_id=city_id).order_by('name')
            except (ValueError, TypeError):
                pass  # invalid input from the client; ignore and fallback to empty City queryset
        elif self.instance.pk:
            #self.fields['vanue'].queryset = self.instance.country.city.vanue_set.order_by('name')
            self.fields['vanue'].queryset = self.instance.city.vanue_set.order_by('name')
        #area
        self.fields['area'].queryset = City.objects.none()
        if 'vanue' in self.data:
            try:
                vanue_id = int(self.data.get('vanue'))
                self.fields['area'].queryset = Area.objects.filter(vanue_id=vanue_id).order_by('name')
            except (ValueError, TypeError):
                pass  # invalid input from the client; ignore and fallback to empty City queryset
        elif self.instance.pk:
            #self.fields['vanue'].queryset = self.instance.country.city.vanue_set.order_by('name')
            self.fields['area'].queryset = self.instance.vanue.area_set.order_by('name')

     

views.py

from django.shortcuts import render
from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse_lazy

from .models import Area, Person, City, Vanue
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')
    context = {'cities': cities}
    return render(request, 'hr/city_dropdown_list_options.html', context)

def load_vanues(request):
    city_id = request.GET.get('city')    
    vanues = Vanue.objects.filter(city_id=city_id).order_by('name')
    context = {'vanues': vanues}
    return render(request, 'hr/vanue_ddl.html', context)

def load_areas(request):
    vanue_id = request.GET.get('vanue')    
    areas = Area.objects.filter(vanue_id=vanue_id).order_by('name')
    context = {'areas': areas}
    return render(request, 'hr/area_ddl.html', context)

urls.py

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('ajax/load-vanues/', views.load_vanues, name='ajax_load_vanues'),
    path('ajax/load-areas/', views.load_areas, name='ajax_load_areas'),
]

person_form.html

area_ddl.html

<option value="">---------</option>
{% for vanue in vanues %}
<option value="{{ area.pk }}">{{ area.name }}</option>
{% endfor %}

Я также ссылаюсь на эту статью Как реализовать трехсторонний зависимый/цепочечный выпадающий список в Django?

Вернуться на верх