Django -filter - группировать похожие значения с разными первичными ключами в форме - PullRequest
0 голосов
/ 17 апреля 2020

Моя цель - отфильтровать модель, которая относится к растениям. Ниже приведена сокращенная версия моей модели:

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 очень проста c всего с двумя полями:

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

Дело в том, что запись для рода будет иногда иметь то же значение для 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

1 Ответ

1 голос
/ 18 апреля 2020

Кажется, что вы действительно ищете 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']
...