Django-filter-以类似的形式将具有不同主键的值分组

问题描述 投票:0回答:1

我的目标是过滤涉及植物的模型。下面是我的模型的缩写:

class Plant(models.Model):

    sku = models.CharField('SKU', max_length=14)
    name = models.CharField('Name', max_length=50)
    genus = models.ForeignKey(Genus, on_delete=models.SET_NULL, null=True, blank=True)

    class Meta:
        ordering = ['genus', 'name']

    def __str__(self):
        return self.name

我的相关模型Genus非常简单,只有两个领域:

class Genus(models.Model):
    common = models.CharField('Common Genus', max_length=100)
    latin = models.CharField('Latin Genus', max_length=100)

    class Meta:
        ordering = ['common']
        verbose_name_plural = 'genera'

    def __str__(self):
        return self.common

这里的意思是,Genus的条目有时与latin的值相同。例如Cherry,Peach和Almond都是prunus,但每个都有自己的条目。

{
    [
        'common': 'Cherry',
        'latin': 'Prunus'
    ],
    [
        'common': 'Almond',
        'latin': 'Prunus'
    ],
    [
        'common': 'Peach',
        'latin': 'Prunus'
    ]
}

我使用django-filter过滤这些值时出现问题。我有一个通用名称过滤器和一个拉丁名称过滤器。通用名称过滤器很简单,因为通用名称将始终是唯一的,但是拉丁名称在许多条目中可能是通用的。

class LatinChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return obj.latin

class LatinFilter(django_filters.ModelChoiceFilter):
    field_class = LatinChoiceField

class ProductFilter(django_filters.FilterSet):
    genus__common = django_filters.ModelChoiceFilter(queryset=Genus.objects.all(), label='Genus')
    latin_q = Genus.objects.all().order_by('latin')
    genus__latin = LatinFilter(queryset=latin_q, label='Latin', field_name='genus')
    class Meta:
        model = Product
        fields = ['genus__common', 'genus__latin']

这将为我提供大部分,但是问题是ModelChoiceFilter将重复拉丁名称的每个值,给了我一个select输入,该输入多次重复“ Prunus”,每个重复仅与Genus模型条目的主键有关。

http://127.0.0.1:8000/plants/?genus__latin=7

产品:

Almond

同时:

http://127.0.0.1:8000/plants/?genus__latin=4

产品:

Cherry

如何将所有类似的拉丁值按名称或一组主键分组在一起?

http://127.0.0.1:8000/plants/?genus__latin='Prunus'
http://127.0.0.1:8000/plants/?genus__latin=7,4,2

应产生:

Almond, Cherry, Peach
django django-filter
1个回答
0
投票

似乎您正在寻找的实际上是AllValuesFilter。有了它,您的代码将如下所示:

class ProductFilter(django_filters.FilterSet):
    genus__common = django_filters.ModelChoiceFilter(queryset=Genus.objects.all(), label='Genus')
    genus__latin = AllValuesFilter(label='Latin')
    class Meta:
        model = Product
        fields = ['genus__common', 'genus__latin']
© www.soinside.com 2019 - 2024. All rights reserved.