2013-05-16 16 views
7

Ich verwende Annotate, um eine Eigenschaft zu einem Objekt hinzuzufügen, das ich dann für order_by verwenden kann. Ich möchte jedoch auf ein Feld einer Beziehung in einer Beziehung eingehen. Ich weiß, dass ich irgendwie mit Double-Underscore-Notation auf das Feld kommen könnte, aber ich kann mich einfach nicht darum kümmern.Django: wie order_by auf einem verwandten Feld eines verwandten Felds

Hier sind die Modelle:

class Group(Taggable, Uploadable): 
    name   = models.CharField(max_length=250, db_index=True) 
    description  = models.TextField(max_length=5000, null=True, 
         blank=True, db_index=True) 
    private   = models.BooleanField(default=False) 
    members   = models.ManyToManyField(User, null=True, 
         related_name='members', through='GroupToUser') 
    pending_members = models.ManyToManyField(User, null=True, 
         related_name='pending_members') 
    admin   = models.ForeignKey(User, null=True) 
    timestamp  = models.DateTimeField(auto_now_add=True) 
    author   = models.ForeignKey(User, related_name='author') 

class Discussion(Taggable, Uploadable): 
    author  = models.ForeignKey(User) 
    title  = models.CharField(max_length=250, db_index=True) 
    description = models.TextField(max_length=5000, null=True, 
        blank=True, db_index=True) 
    group  = models.ForeignKey(Group, null=True) 
    timestamp = models.DateTimeField(auto_now_add=True) 

class DiscussionResponse(Uploadable): 
    author  = models.ForeignKey(User) 
    discussion = models.ForeignKey(Discussion) 
    message = models.TextField(max_length=5000) 
    timestamp = models.DateTimeField(auto_now_add=True) 

So kann eine Diskussion optional mit einer Gruppe zugeordnet werden, und DiscussionResponses sind mit einer Diskussion verbunden. Was ich tun möchte, ist, die letzte DiscussionResponse in allen Diskussionen zu finden, die mit einer Group verbunden sind, falls sie existiert, und nach dieser zu sortieren.

Ich habe so weit wie diese bekommen:

Group.objects.filter(some_filtering).distinct().annotate(
    last_response=Max('some__reverse__relationship__timestamp').order_by(
     '-last_response') 

Ich kann einfach nicht scheinen, den richtigen Weg, um herauszufinden, zu dem Zeitstempel auf einem DiscussionResponse in diesem Fall zu erhalten.

UPDATE: Sie können tatsächlich durch einen annotierten Wert bestellen. Hier ist ein Beispiel mit einem order_by auf dem Zeitstempel eines Siehe auch:

>>> groups = Group.objects.all().annotate(
     last_response=Max('discussion__timestamp')).order_by('-last_response') 
>>> for group in groups: 
...  print(group.id, group.last_response) 
...  
... 
(2L, datetime.datetime(2013, 5, 8, 15, 32, 31)) 
(1L, None) 
(3L, None) 
(4L, None) 
(6L, None) 
(7L, None) 
(8L, None) 
(9L, None) 

In diesem Fall wird nur die Gruppe # 2 hat Diskussionen im Zusammenhang, so dass es nach oben bewegt wurde; der Rest behält die natürliche Ordnung bei. Was ich wirklich gerne tun würde, sind Bewegungsgruppen, bei denen die letzten Antworten zu Diskussionen an die Spitze der Liste verschoben wurden. Deshalb dachte ich, 'discussion__discussionresponse__timestamp' würde funktionieren, aber es scheint nicht zu sein.

+0

ich folgendes versucht haben, von denen keines gearbeitet: 'discussion__discussionresponse__timestamp',' discussion_set__discussionresponse__timestamp' und 'diskussionssatz__discussionresponse__zeitstempel' – foresmac

+0

Ich verstehe nicht, was Sie zu erreichen versuchen. Zum Beispiel deklarieren Sie 'last_response = Max (...)', was Ihnen einen Zeitstempel gibt, und dann bestellen Sie_mit diesem Wert, müssen Sie nach Spalte sortieren, keinen Wert, habe ich Recht? Was Sie wollen, ist Reihenfolge von Timestamp Colum ?? –

+0

Sie können 'order_by' auf einen annotierten Wert setzen; Ich habe den Trick schon einmal benutzt. Das Problem ist, ich kann nicht auf den Zeitstempel der DiscussionResponses im Zusammenhang mit den Diskussionen zu einer Gruppe zu kommen scheinen. – foresmac

Antwort

1

Ok, anscheinend ist es ist nur 'discussion__discussionresponse__timestamp'. Ich versuchte es in dem Django-Shell und es hat nicht funktioniert nach einer neuen DiscussionResponse speichern, aber es funktionierte einige Minuten später, als ich es wieder versucht:

>>> groups = Group.objects.all().annotate(last_response=Max(
     'discussion__discussionresponse__timestamp')).order_by('-last_response') 
>>> for group in groups: 
...  print(group.id, group.last_response) 
...  
... 
(2L, datetime.datetime(2013, 5, 16, 14, 56, 22)) 
(1L, None) 
(3L, None) 
(4L, None) 
(6L, None) 
(7L, None) 
(8L, None) 
(9L, None) 
>>> 

Wenn jemand weiß, warum es nicht richtig funktionierte nach dem Speichern ein neues Objekt für die Datenbank, aber hat später funktioniert, das wäre wahrscheinlich eine nützliche Information.

Hier ist eine andere Sicht auf die Abfrage mit Diskussionen/Antworten zu einer anderen Gruppe haben soeben für zusätzliche Verifikation:

>>> groups = Group.objects.all().annotate(last_response=Max('discussion__discussionresponse__timestamp')).order_by('-last_response') 
>>> for group in groups: 
...  print(group.id, group.last_response) 
...  
... 
(4L, datetime.datetime(2013, 5, 16, 15, 25, 40)) 
(2L, datetime.datetime(2013, 5, 16, 15, 16, 46)) 
(1L, None) 
(3L, None) 
(6L, None) 
(7L, None) 
(8L, None) 
(9L, None) 
>>> 
+0

Fühlen Sie sich frei, als beantwortet zu markieren. – stellarchariot

Verwandte Themen