Использование F () с аннотациями, включая другое выражение запроса в Django - PullRequest
0 голосов
/ 25 июня 2018

Это мой (упрощенный) вариант использования:

from django.db import models

class MyType(models.Model):
    whatever = models.CharField()

class A(models.Model):
    type = models.ForeignKey(MyType)

class B(models.Model):
    my_type = models.ForeignKey(MyType)
    position = models.IntegerField(default=0)

Я хочу, чтобы элементы из A сортировались по полю позиции B .Итак, мне нужно сначала объединить таблицы A и B на MyType.Попробовал это:

A.objects.all().annotate(position=B.objects.get(my_type=models.F('type')).position).order_by('position')

Получил ошибку:

FieldError: Cannot resolve keyword 'type' into field. Choices are: my_type, my_type_id, position

Итак, Джанго понимает, что F('type') пытается получить значение поля 'type' модели B. Что,конечно, не существует. Я хотел использовать поле 'type' модели A . Похоже, что F относится к внутреннему запросу, а не к внешнему.

Итак, есть ли лучший способ получить то, что я хочу?

1 Ответ

0 голосов
/ 29 июня 2018
# Django 1.11 already includes OuterRef and Subquery, but I'm working with Django 1.9
from django_subquery.expressions import OuterRef, Subquery

items = B.objects.filter(my_type=OuterRef('type')).order_by('position')
A.objects.all().annotate(position=Subquery(items.values('position')[:1])).order_by('position')

Получить django_subquery для версий Django старше 1.11 из здесь

...