Django链式过滤结果基于manytomany字段中的selection

Django chain filtering results based on selection in manytomany fields

我有以下型号:

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

class State(models.Model):
    country = models.ForeignKey(Country, on_delete=models.CASCADE)
    name =  models.CharField(max_length=50, null=False, blank=False)

class Species(models.Model):
    name = models.CharField(max_length=50, null=False, blank=False)
    country =models.ManyToManyField(Country)
    state =models.ManyToManyField(State)

假设我在表单或管理字段中添加了多个国家。有没有一种方法可以根据我在国家/地区字段中 select 编辑的内容来过滤州字段的结果?

这方面的一个例子是:

Countries: States

USA: CA, VA, NV, OR

Mexico: PUB, JAL, SIN

Canada: NU, ON, QC

如果我 select USACanada 表单上的状态字段将产生:

NU, ON, QC, 
CA, VA, NV, OR

我能找到的做类似事情的最接近的东西是 django-smart-select,但它不适用于我的情况。

我会用Ajax+JS来实现这个。我会按照这些思路做一些事情(我没有测试过这段代码):

HTML :

<select name="country">
  <option value="">Choose a country</option>
  <option value="USA">USA</option>
  <option value="Mexico">Mexico</option>
  <option value="Canada">Canada</option>
</select>

<select name="state" disabled>
  <option value="">Choose a state</option>
</select>

JS :

$('select[name="country"]').on('change', function() {
  var country = $(this).val();
  var states = [];
  $('select[name="state"] option:gt(0)').remove(); // cleaning: removes all options except the first

  if (!(country)) {
    $('select[name="state"]').prop("disabled", true);
  } else {
    $.ajax({
      url: "{% url 'get_states' %}",
      dataType: "json",
      data: {
        country: country
      },
      success: function(data) {
        data = JSON.parse(data);
        for (var key in data) {
          $('select[name="state"]').append(
            $('<option>', {
              value: key,
              text: data[key]
            })
          );
        }
      }
    });
    $('select[name="state"]').prop("disabled", false);
  }
});

在urls.py中:

url(r'^getstates$', 'myapp.views.get_states', name='get_states'),

在views.py中:

from django.shortcuts import HttpResponse
import json
from myapp.models import Country, State


def get_states(request):
    if request.is_ajax():
        country = request.GET.get('country', '')
        states = State.objects.filter(country__name=country)
        state_dict = {}
        for state in states:
            state_dict[state.pk] = state.name
        return HttpResponse(json.dumps(state_dict))

希望对您有所帮助!