Sto costruendo un sito Django per discussioni. Gli utenti possono partecipare alle discussioni e possono anche esprimere voti di approvazione per discussioni e messaggi nelle discussioni. Un modello di dati semplificata è la seguente:Django: ordina un queryset sommando i campi annotati?
class Discussion:
name = models.CharField(max_length=255)
class Message:
owner = models.ForeignKey(User, related_name='messages')
body = models.TextField()
discussion = models.ForeignKey(Discussion, related_name='messages')
class MessageApprovalVote:
owner = models.ForeignKey(User, related_name='message_approval_votes')
message = models.ForeignKey(Message, related_name='approval_votes')
class DiscussionApprovalVote:
owner = models.ForeignKey(User, related_name='discussion_approval_votes')
discussion = models.ForeignKey(Discussion, related_name='approval_votes')
voglio selezionare i primi 20 "più attivo" discussioni, il che significa che l'ordinazione dalla somma del numero di messaggi, il numero totale di approvazione messaggio voti, e il numero di approvazione discussione vota per quella discussione, o (in pseudocodice):
# Doesn't work
Discussion.objects.
order_by(Count('messages') +
Count('approval_votes') +
Count('messages__approval_votes'))
Uso delle annotazioni, posso calcolare i totali di ciascuno dei fattori di tre gol:
scores = Discussion.objects.annotate(
total_messages=Count('messages', distinct=True),
total_discussion_approval_votes=Count('approval_votes', distinct=True),
total_message_approval_votes=Count('messages__approval_votes', distinct=True))
ho poi t hought ero a qualcosa quando ho trovato il metodo extra
:
total_scores = scores.extra(
select={
'score_total': 'total_messages + total_discussion_approval_votes + total_message_approval_votes'
}
)
e sarebbe quindi in grado di fare:
final_answer = total_scores.order_by('-score_total')[:20]
ma la chiamata extra
dà un DatabaseError
:
DatabaseError: column "total_messages" does not exist
LINE 1: SELECT (total_votes + total_messages + total_persuasions) AS...
e così sono stato sventato. Il metodo extra
non fa riferimento ai campi annotate
d? C'è un altro modo per fare ciò che sto cercando di fare, a meno di usare una query sql raw? Sto usando Postgres se questo fa la differenza.
Qualsiasi approfondimento sarebbe molto apprezzato!
https : //docs.djopoproject.com/en/dev/topics/db/aggregation/#aggregating-annotations Non è abbastanza utile? – karthikr
Un aggregato non sembra essere d'aiuto in questo caso, perché ho bisogno di recuperare un queryset degli oggetti di discussione, non solo i conteggi di ciascun fattore di punteggio. – davidscolgan