Фильтрация данных из объединяющей таблицы в Django по внешнему ключу

У меня есть классы моделей, которые выглядят следующим образом:

class Wine(models.Model):
    wine_id = models.IntegerField(blank=True, null=False, primary_key=True)
    wine_name = models.TextField(blank=True, null=True)
    wine_type = models.TextField(blank=True, null=True)
    wine_year = models.IntegerField(blank=True, null=True)
    wine_alcohol = models.FloatField(blank=True, null=True)
    wine_country = models.TextField(blank=True, null=True)
    wine_price = models.FloatField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'wine'

class Flavor(models.Model):
    flavor_id = models.IntegerField(primary_key=False)
    flavor_name = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'flavor'

и одна соединительная таблица между этими двумя:

class FlavorWine(models.Model):
    flavor_wine_id = models.IntegerField(blank=True, null=False, primary_key=True)
    flavor_group = models.TextField(blank=True, null=True)
    flavor_count = models.IntegerField(blank=True, null=True)
    wine_id = models.ForeignKey('Wine', on_delete=models.DO_NOTHING)
    flavor_id = models.ForeignKey('Flavor', on_delete=models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'flavor_wine'

Теперь, когда я пытаюсь получить данные, я получаю ошибки. Я пробовал использовать примеры, приведенные в: Django Filter by Foreign Key и Django: join two tables, но безуспешно.

Я пытался:

wines = Wine.objects.filter(wine_id=wine_id)
wine_flavor = FlavorWine.objects.filter(wine_id__in=wines.values('wine_id'))

return HttpResponse(serializers.serialize('json', wine_flavor, fields=('wine_id', 'flavor_group', 'flavor_count', 'flavor_id')))

и

wine_flavor = serializers.serialize('json', FlavorWine.objects.filter(wine_id_id__gt=wine_id), fields=('wine_id', 'flavor_group', 'flavor_count', 'flavor_id'))

и

wine_flavor = serializers.serialize('json', FlavorWine.objects.filter(wine_id__flavorwine__exact=wine_id), fields=('wine_id', 'flavor_group', 'flavor_count', 'flavor_id'))

И различные комбинации, которые были предложены, но ни одна из них не работает, либо сбой при соединении таблиц, либо не может найти нужное поле. Я всегда получаю подсказку:

HINT: Возможно, вы хотели сослаться на колонку "flavor_wine.wine_id".

То есть, это именно та колонка, на которую я пытаюсь сослаться, но я не могу найти правильный способ сделать это.

Для фильтрации по ForeignKey можно просто передать экземпляр этой модели

В вашем первом методе:

wine_flavor = FlavorWine.objects.filter(wine_id__in=wines.values('wine_id'))

если wine_id является экземпляром Wine model, то вы можете просто написать

 wine_flavor = FlavorWine.objects.filter(wine_id=wine_id)

и если wine_id является списком идентификаторов из Wine model, то вы можете просто сделать следующее:

wine_flavor = FlavorWine.objects.filter(wine_id__id__in=wine_id)

Позвольте мне объяснить, что делает приведенная выше строка,

предположим, что wine_id = ['1', '2', '3',....]. где '1' представляет id из Wine model

отфильтруйте их из FlavorWine(FlavorWine.objects.filter)

Где id из Модель вина(wine_id__id) находится в list(wine_id)

(если вам нужна дополнительная помощь, прокомментируйте ниже, я могу обновить свой ответ соответствующим образом)

Итак, чтобы отфильтровать связанные модели по foreignkey, достаточно просто использовать функцию prefetct_ralated, которая принимает аргумент связанного имени модели. Как в моем примере ниже. Вот ссылка, чтобы прочитать больше, чтобы помочь вам понять запрос с prefetch related. https://docs.djangoproject.com/en/4.0/ref/models/querysets/#prefetch-related

wines = Wine.objects.prefetch_related('flavorwine_set').filter(wine_id=wine_id)
wine_flavor = FlavorWine.objects.prefetch_related('flavorwine_set').filter(wine_id__in=wines.values('wine_id'))

Попробуйте воспользоваться этой статьей, https://www.django-antipatterns.com/antipattern/foreign-key-with-id-suffix.html и посмотрите, устранит ли она вашу проблему.

Основная причина, по которой это проблема, заключается в том, что сама .other_model не хранит id. Действительно, Django создает неявное двойное поле с суффиксом _id, которое хранит первичный ключ

.
Вернуться на верх