在django admin中为外键创建链接列表

时间:2016-07-05 05:32:08

标签: django django-admin django-autocomplete-light

我有一些像这样链接的外键关系:

class Continent(models.Model):
    continent = models.CharField(max_length=30)

class Country(models.Model):
    country = models.CharField(max_length=30)
    continent = models.ForeignKey(Continent)

class City(models.Model):
    city = models.CharField(max_length=30)
    country = models.ForeignKey(Country)

class Person(models.Model):
    name = models.CharField(max_length=30)
    continent = models.ForeignKey(Continent)
    country = models.ForeignKey(Country)
    city = models.ForeignKey(City)

在人员管理员创建新项目视图中,我希望根据选择的大陆等更改国家和城市列表。 我试过LinkedSelect of django suit,但我认为这不是为了这个。 我读了一下django select2,但我没有看到任何支持。 是否有包可以帮助的任何想法?

更新:我遇到了this

表明django smart选择。我尝试过这个。有两个问题: - 它要求您修改模型,使其成为红色标志。 - 它以类别的形式显示列表,但它仍然允许您选择不合适的错误项目。 ( show_all 不适用于GroupedForeignKey)

我有个好主意。由于我想使用django-autocomplete-light使用自动完成,如果我可以添加一个事件处理程序,当你选择第一个列表时,然后修改第二个列表的自动完成URL以传入一个额外的参数,那么整个链将工作。我坚持的是当我更改url(data-autocomplete-light-url)时,它没有生效。我不知道如何触发它重新加载。

1 个答案:

答案 0 :(得分:1)

幸运的是,这实际上是part of django-autocomplete-light

您必须创建自己的表单(如果尚未创建):

class PersonForm(forms.ModelForm):

    class Meta:
        model = Person
        fields = ('__all__')
        widgets = {
            'country': autocomplete.ModelSelect2(url='country-autocomplete'
                                                 forward=['continent']),
            'city': autocomplete.ModelSelect2(url='city-autocomplete'
                                              forward=['country']),
        }

更新您的自动填充功能:

class CountryAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        if not self.request.is_authenticated():
            return Country.objects.none()

        qs = Country.objects.all()

        continent = self.forwarded.get('continent', None)

        if continent:
            qs = qs.filter(continent=continent)

        if self.q:
            qs = qs.filter(country__istartswith=self.q)

        return qs

class CityAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        if not self.request.is_authenticated():
            return City.objects.none()

        qs = City.objects.all()

        country = self.forwarded.get('country', None)

        if country:
            qs = qs.filter(country=country)

        if self.q:
            qs = qs.filter(city__istartswith=self.q)

        return qs

在ModelAdmin中使用新表单:

class PersonAdmin(admin.ModelAdmin):
    form = PersonForm