2016-10-10 8 views
1
class Business(models.Model): 
    manager = models.ForeignKey(User, on_delete=models.CASCADE) 
    #... 

class Event(models.Model): 
    business = models.ForeignKey(Business, on_delete=models.CASCADE) 

    text = models.TextField() 
    when = models.DateTimeField() 
    likes = GenericRelation('Like') 

class Like(models.Model): 
    person = models.ForeignKey(User, on_delete=models.CASCADE) 

    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

    date = models.DateTimeField(auto_now=True) 

この構造はmodels.pyです。重要なモデルの説明を次に示します。
イベントモデルには、特定のビジネスオブジェクトにリンクする「ビジネス」フィールドがあります。このフィールドにはさらに「マネージャー」フィールドがあります。また、イベントモデルには、イベントが発生する日付を記述する "when"フィールドがあります。
Likeモデルでは、特定のEventオブジェクトにリンクできる一般的な外部キーフィールドと、誰が好きなのか、そのイベントに与えられたのかを記述する "person"と "date"フィールドもあります。JOIN式と一般的な関係のDjango ORMへの翻訳クエリ

目標は、対象となるユーザーがお気に入りのイベントをすべてユーザーページに表示し、そのユーザーがすべてのイベントを表示するようになりました。これは単に、このSQLコマンドを使用して行うことができます。

SELECT event.* 
FROM event 
INNER JOIN 
    business 
    ON (event.business_id = business.id) 
LEFT JOIN 
    'like' 
    ON (event.id = object_id AND content_type_id = 17) 
WHERE ('like'.person_id = 1 OR business.manager_id = 1); 

しかし、今の結果は、すでに述べたようで、「日付」と「とき」イベントモデルでで、ソートする必要があります。イベントオブジェクトがLikeオブジェクトから派生している場合、そのLikeオブジェクトの "date"でソートする必要があります。それ以外の場合は、イベントの "when"でソートする必要があります。 。

SELECT event.* 
FROM event 
INNER JOIN 
    business 
    ON (event.business_id = business.id AND business.manager_id = 1) 
LEFT JOIN 
    'like' 
    ON (event.id = object_id AND content_type_id = 17 AND person_id = 1) 
ORDER BY COALESCE('like'.date, event.'when') DESC; 

そして私は、DjangoのORMへの最後のクエリを変換するために今持っているが、私は完全にその部分に迷ってしまいました:したがって、ここでは、最終的な生のクエリがどのように見えるかです。誰でも助けてくれますか?前もって感謝します!

+0

をここで上記のクエリに近い私の試みだが、まだありません。 order_by(Coalesce( 'likes__date'、 'when'))desc()) '' '' '' '' '' '' '' '' '' ' – MikiSoft

答えて

0

もう一日の苦労の末、私はついにそれを解決しました。

from django.db.models import Case, When, F 

Event.objects.filter(\ 
     Q(business__manager=person) | \ 
     Q(likes__person=person)) \ 
    .order_by(\ 
     Case(\ 
      When(likes__person=person, then=F('likes__date')), \ 
      default=F('when')) \ 
    .desc()) 

がここにあります:それは上から同じクエリを生成しないと(それが照会イベントのすべての同類を選択だから)それのように効率的ではありませんんが、それはORMでそれを行うための唯一の良い方法だように、それはそうですそれが生成するどのようなSQL: `Event.objects.filter(Q(pk__in = Like.objects.filter(PERSON_ID = 1、content_type_id = 17):

SELECT event.* 
FROM event 
INNER JOIN 
    business 
    ON (event.business_id = business.id) 
LEFT OUTER JOIN 
    'like' 
    ON (event.id = object_id AND content_type_id = 17) 
WHERE (business.manager_id = 2 OR 'like'.person_id = 2) 
ORDER BY CASE 
    WHEN 'like'.person_id = 2 THEN 'like'.date 
    ELSE event.'when' 
END DESC; 
関連する問題