Django 表单的 ModelChoiceField 的 QuerySet

1 投票
4 回答
4007 浏览
提问于 2025-04-16 05:47

我有一个表单,里面使用了以下字段。

contact_country = forms.ModelChoiceField(queryset=Country.objects.all())

国家模型看起来是这样的

class Country(models.Model):
    iso = models.CharField(max_length=2)
    name = models.CharField(max_length=80)
    printable_name = models.CharField(max_length=80)
    iso3 = models.CharField(max_length=3,null=True, blank=True)
    numcode = models.IntegerField(null=True, blank=True)
    special = models.BooleanField(default=False)

    def __unicode__(self):  
        return self.printable_name

    class Meta:
        ordering = [ 'printable_name' ]

这里的“special”字段表示这个国家是“特别的”。如果一个国家被标记为“特别”,我希望它能排在其他国家的前面,就像你在网上看到的那样(比如说,像澳大利亚、英国和美国这些讲英语的国家通常会排在选择列表的最上面,然后再是其他国家)。

这样做在QuerySet中可以实现吗?还是说我应该找其他方法?

4 个回答

0

你可以改变默认的排序方式

class Meta:
    ordering = [ '-special', 'printable_name' ]

你也可以写一个自定义管理器,不过这样做不太划算……

0

这个还没经过测试,所以你可以试试看,但可能达不到你想要的效果……

在你的视图里这样做:

specials = Country.objects.filter(special=True)
all_of = Country.objects.all()

# worst thing is, this is a list, not a queryset...
new_list = list(specials)+list(all_of)

# add new object to you form...
YourForm.base_fields['contact_country'] = forms.ChoiceField(choices=[(x.id,x) for x in new_list])

你的问题在于,你是用一个列表来创建列表,而不是直接从查询集中获取数据。

这样做可以解决你的问题,虽然看起来有点不太好,但这是我在模型表单无法帮到你的时候用过的一个解决办法……

2

这段代码是说,contact_country 是一个选择框,里面的选项是从数据库中获取的国家列表,并且这些国家是按照某个特殊的顺序排列的。具体来说,Country.objects.order_by('special') 这部分是用来从数据库中取出国家信息,并按照名为“special”的字段进行排序。简单来说,就是让用户在选择国家时,看到的国家列表是经过特别排序的。

撰写回答