Если я вас правильно понял, для каждого типа bottle вы хотите:
- найти свои баллы
- проверить, принято ли оно.
Существует два способа решения вашей проблемы:
- Получить
OrganisationBottleType
набор запросов и сопоставить OrganisationBottleType
объекты с соответствующими объектами в BottleType
в python с помощью .prefetch_related()
и Prefetch()
объект - Аннотировать
BottleType
набор запросов с соответствующими объектами из OrganisationBottleType
с помощью .annotate()
и Subquery()
Оба варианта описаны ниже:
1. Используйте .prefetch_related
с Prefetch
объектом
Дано:
queryset
- BottleType
queryset organisation_id
- идентификатор необходимого организация
Решение:
queryset = queryset.prefetch_related(
Prefetch(
'organisation_bottle_types',
queryset= OrganisationBottleType.objects.filter(organisation_id=organisation_id)
)
)
После этого вы можете получить желаемые данные таким образом:
for bottle_type in queryset:
if bottle_type.organisation_bottle_types.all():
related_object = bottle_type.organisation_bottle_types.all()[0]
is_accepted = related_object.is_accepted
points = related_object.points
else:
is_accepted = False
points = None
2. Используйте SubQuery
Дано:
queryset
- BottleType
queryset organisation_id
- id необходимой организации
Решение:
organisation_bottle_types = OrganisationBottleType.objects.filter(organisation_id=organisation_id, bottle_type=OuterRef('id'))
queryset = queryset.annotate(
is_accepted=Subquery(organisation_bottle_types.values('is_accepted')[:1])
).annotate(
points=Subquery(organisation_bottle_types.values('points')[:1], output_field=BooleanField())
)
После того, как вы сможете сделать:
for bottle_type in queryset:
is_accepted = bottle_type.is_accepted
points = bottle_type.points
Продолжить:
Лично я 'd go со вторыми параметрами, потому что он будет выполнять все сопоставления logi c на уровне базы данных, а не на уровне кода.
Первый вариант лучше, когда вам нужно сопоставить весь объект, а не всего несколько полей (например, points
и is_accepted
из вашего вопроса)