Фильтрация обратного отношения "один ко многим" в Django

У меня есть модель с именем Item и другая модель с именем ItemSynonym с отношением один ко многим следующим образом:

from django.db import models
from django.conf import settings

from project.utils.models import UUIDModel 

class Item(UUIDModel):
    name = models.CharField(max_length=200)

class ItemSynonym(UUIDModel):
    marker = models.ForeignKey(
        Marker,
        on_delete=models.CASCADE,
        related_name="synonyms",
    )
    name = models.CharField(max_length=200)

Теперь я хочу добавить новое поле в модель ItemSynonym под названием код языка, чтобы оно стало:

class ItemSynonym(UUIDModel):
    marker = models.ForeignKey(
        Marker,
        on_delete=models.CASCADE,
        related_name="synonyms",
    )
    language_code = models.CharField(
        db_index=True,
        max_length=8,
        verbose_name="Language",
        choices=settings.LANGUAGES,
        default=settings.LANGUAGE_CODE,
    )
    name = models.CharField(max_length=200)

Как бы я ни хотел фильтровать, мне интересно, можно ли как-то фильтровать синонимы, изменяя только модели, чтобы мне не пришлось рыться во всей кодовой базе и фильтровать синонимы по отдельности, так что что-то вроде:

class Item(UUIDModel):
    name = models.CharField(max_length=200)
    synonyms = models.FilteredRelation(
        "all_synonyms",
        condition=models.Q(language_code=get_language()),
    )

class ItemSynonym(UUIDModel):
    marker = models.ForeignKey(
        Marker,
        on_delete=models.CASCADE,
        related_name="all_synonyms",
    )
    language_code = models.CharField(
        db_index=True,
        max_length=8,
        verbose_name="Language",
        choices=settings.LANGUAGES,
        default=settings.LANGUAGE_CODE,
    )
    name = models.CharField(max_length=200)

Хотя очевидно, что вышеописанное не работает, иначе бы меня здесь не было. Я также попробовал добавить аннотацию для FilteredRelation inside a custom manager for Item`, но по какой-то причине аннотация даже не доступна как свойство.

Я довольно новичок в Django, но я уверен, что это не редкая проблема, поэтому я был бы также благодарен за любую информацию о том, каков идиоматический способ фильтрации таких отношений.

Да, вы можете фильтровать при предварительной выборке с помощью Prefetch [Django-doc] объекта:

from django.db.models import Prefetch

items = Item.objects.prefetch_related(
    Prefetch('all_synonyms', ItemSynonym.objects.filter(language_code='tr'))
)

например, если мы получим эти и перечислим их:

for item in items:
    for synonym in item.all_synonyms.all():
        print(synonym)  # only Turkish ones

Таким образом, мы получим только турецкие

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