0

次のコードがあります。

def get_elements(self, obj):
  book_elements = Element.objects.filter(book__pk=obj.id)
  elements = Element.objects.filter( (Q(book__pk=obj.id) | Q(theme__pk=obj.theme_id)), ~Q(pk__in = [o.element_id for o in book_elements if o.element_id]))
  serializer = GetElementSerializer(elements, context=self.context, many=True)

elements 変数は、Q オブジェクトの実装を使用したクエリです。ただし、まったく同じ値のセットを参照しますQ(book__pk=obj.id)。2 つのクエリを実行する必要がないように、リスト内包表記book_elementsの内部を参照するにはどうすればよいですか。Q(book__pk=obj.id)次のようなもの:

def get_elements(self, obj):
  elements = Element.objects.filter( (Q(book__pk=obj.id) | Q(theme__pk=obj.theme_id)), ~Q(pk__in = [o.element_id for o in Q(book__pk=obj.id) if o.element_id]))
  serializer = GetElementSerializer(elements, context=self.context, many=True)

要求された私の要素モデル:

class Element(models.Model):
  name = models.CharField(max_length=100)
  pub_date = models.DateTimeField('date published', auto_now_add=True)
  mod_date = models.DateTimeField('modified date', auto_now=True)
  book = models.ForeignKey(Book, blank=True, null=True, related_name='elements')
  book_part = models.ForeignKey(BookPart)
  theme = models.ForeignKey(Theme, blank=True, null=True, related_name='elements')
  element = models.ForeignKey('self', blank=True, null=True, related_name='parent')
  def __str__(self):
    return self.name

どんな助けでも大歓迎です!

4

2 に答える 2

0

サブクエリ ソリューションを使用した 1 つのクエリを次に示します。

elements = Element.objects.filter( 
    (Q(book__pk=obj.id) | Q(theme__pk=obj.theme_id)),
    ~Q(pk__in = Element.objects.filter(
            book__pk=obj.id,
            element__isnull=False
        ).values_list('element', flat=True)
    )
)

これはデータベースに一度だけヒットします。

ところで、あなたが実際に達成しようとしていることを読んだ後:

この本のブック ID とテーマ ID に等しい book_id または theme_id を持つすべての要素を取得します。ただし、この本の別の要素と FK 関係を持つ要素は除きます

ORM のやり方では、これは次のようにも達成できると思います。

elements = Element.objects \
    .filter(Q(book_id=book.id)|Q(theme_id=book.theme_id)) \
    .exclude(element__in=book.elements.all()) #not tested, if throws an error transform it into: book.elements.values_list('id', flat=True)

繰り返しますが、これはデータベースに 1 回だけヒットquerysetsDjangoますqueryset

于 2015-03-31T22:32:22.303 に答える