怎么用Django实现三向依赖/链式下拉列表?

本教程将介绍如何用Django实现三向依赖/链式下拉列表?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

怎么用Django实现三向依赖/链式下拉列表? 教程 第1张

问题描述

我使用的是Django和PostgreSQL。我正在处理一个3向依赖下拉列表。添加国家/地区选择后,省区域将根据所选国家/地区自动更新。选择省份后,县字段仅在刷新页面时打开。如果你能在这方面帮助我,我会很高兴。

mods.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 District(models.Model):
 city = models.ForeignKey(City, on_delete=models.CASCADE)
 name = models.CharField(max_length=30)

 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)
 district = models.ForeignKey(District, on_delete=models.SET_NULL, null=True)

 def __str__(self):
  return self.name

forms.py

from django import forms
from .models import Person, Country, City, District

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

 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:
self.fields['city'].queryset = self.instance.country.city_set.order_by('name')

 def __init__(self, *args, **kwargs):
  super().__init__(*args, **kwargs)
  self.fields['district'].queryset = District.objects.none()

  if 'city' in self.data:
try:
 city_id = int(self.data.get('city'))
 self.fields['district'].queryset = District.objects.filter(city_id=city_id).order_by('name')
except (ValueError, TypeError):
 pass  # invalid input from the client; ignore and fallback to empty District queryset
  elif self.instance.pk:
self.fields['district'].queryset = self.instance.city.district_set.order_by('name')

views.py

def load_cities(request):
 country_id = request.GET.get('country')
 cities = City.objects.filter(country_id=country_id).order_by('name')
 return render(request, 'neighbor/city_dropdown_list_options.html', {'cities': cities})

def load_districts(request):
 city_id = request.GET.get('city')
 districts = District.objects.filter(city_id=city_id).order_by('name')
 return render(request, 'neighbor/district_dropdown_list_options.html', {'districts': districts})

模板.html

<h2>Person Form</h2>
  <form method="post" id="personForm" data-cities-url="{% url 'ajax_load_cities' %}" 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 () {
var url = $("#personForm").attr("data-cities-url");
var countryId = $(this).val();
$.ajax({
  url: url,
  data: {
 'country': countryId
  },
  success: function (data) {
 $("#id_city").html(data);
  }
});
 });
 $("#id_city").change(function () {
var url = $("#personForm").attr("data-districts-url");
var cityId = $(this).val();
$.ajax({
  url: url,
  data: {
 'city': cityId
  },
  success: function (data) {
 $("#id_district").html(data);
  }
});
 });
  </script>

我指的是这里的示例。

推荐答案

    在templates.html文件中,您调用的是相同的URL,因此更改了国家和城市字段的相同视图。您需要创建一个新的URL来处理LOAD_REDICATION视图中的请求。

    进行以下更改

    $("#id_city").change(function () {
      var url = $("#personForm").attr("data-districts-url");
      var cityId = $(this).val();
      $.ajax({
     url: '{% url 'ajax_load_districts' %}',
     data: {
    'city': cityId
     },
     success: function (data) {
    $("#id_district").html(data);
     }
      });
    });
    

    您不需要两次修改init()方法,只需从froms.py中删除这两行即可。(行号22和23)

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

    添加新URL以处理学区的AJAX请求

    path('ajax/load-district/', views.load_districts, name='ajax_load_districts'),
    

您可以克隆此示例,我已经使用了Country、City、Vanue.https://github.com/masbhanoman/django_3way_chained_dropdown_list

好了关于怎么用Django实现三向依赖/链式下拉列表?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。