DjangoAdmin中的limit_choices_to

时间:2013-08-12 09:40:07

标签: django django-models foreign-keys django-forms

我的一个模型包含一个具有数千个实例的模型的ForeignKey字段 当我显示一条记录时,所有这些都被加载到一个下拉列表中,我a)不需要和b)像frack一样慢,特别是在一页上显示多个记录时。 由于下拉的大小,页面大小可以达到3.5mb的倍数。

我想过使用“limit_choices_to”来包含它,但是

country = models.IntegerField(blank=True, null=True)
location = models.ForeignKey(Geonames, limit_choices_to = {'cowcode': country}, related_name='events')

不起作用。 有没有办法做到这一点?

更新
我想要显示什么?
我想要显示上面代码来自Geonames的{​​{1}}中的所有地点(country)。我想只显示 这些地方,而不是所有可能地点的整个列表。

为什么我不需要所有地方?
a)页面加载时间:页面加载3.5分钟太长了 b)见上文:事件发生在某个国家/地区,因此我不需要显示不在该国家/地区的地点

3 个答案:

答案 0 :(得分:2)

如果您使用的是管理界面,则可以在ModelAdmin中使用raw_id_fields:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'
    ordering = ('-publication_date',)
    filter_horizontal = ('authors',)
    raw_id_fields = ('publisher',)

from Django Book:

有时您不希望产生必须选择要在下拉列表中显示的所有相关对象的开销。例如,如果我们的图书数据库增长到包含数千个发布者,则“添加图书”表单可能需要一段时间才能加载,因为它必须加载每个发布者才能在框中显示。

解决此问题的方法是使用名为raw_id_fields的选项。将其设置为ForeignKey字段名称的元组,这些字段将显示在管理员中,带有一个简单的文本输入框()而不是选择。

答案 1 :(得分:2)

您想要的是limit_choices_to了解您的实例,这是不可能的。 您应该做的是在管理表单中设置queryset字段的location属性,类似于:

class EventRecordAdminForm(forms.ModelForm):

    class Meta:
        model = EventRecord

    def __init__(self, *args, **kwargs):
        super(EventRecordAdminForm, self).__init__(*args, **kwargs)
        self.fields['location'].queryset = Geonames.objects.filter(cowcode=self.instance.country)

当然会为您的管理员使用该表单:

class EventRecordAdmin(admin.ModelAdmin):

    form = EventRecordAdminForm

请参阅here for docs

HTH!

答案 2 :(得分:0)

不确定为什么不适合你。但我认为更好的解决方案是使用django-smart-selects。这样您就可以让用户先选择国家/地区。然后,只有当用户首次选择国家/地区时才会填充Geoname下拉列表。

来自文档:

如果您有以下型号:

class Location(models.Model)
    continent = models.ForeignKey(Continent)
    country = models.ForeignKey(Country)
    area = models.ForeignKey(Area)
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

如果您选择一个大陆,只有那些位于该大陆的国家/地区可用,您可以执行以下操作:

from smart_selects.db_fields import ChainedForeignKey 

class Location(models.Model)
    continent = models.ForeignKey(Continent)
    country = ChainedForeignKey(
        Country, 
        chained_field="continent",
        chained_model_field="continent", 
        show_all=False, 
        auto_choose=True
    )
    area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country")
    city = models.CharField(max_length=50)
    street = models.CharField(max_length=100)

此示例假设Country Model有一个continent = ForeignKey(Continent)字段,而Area模型有country = ForeignKey(Country)字段。