2017-06-14 3 views
0

Ich möchte meine Abfrage basierend auf der Anzahl der upvotes bestellen, aber ich kann nicht herausfinden, wie es geht. Es scheint viel zu komplex! (btw bin ich zu verkomplizieren Dinge?)Bestellung Abfragen auf der Grundlage der meisten upvotes

so hier ist mein models.py

class Activity(models.Model): 
    FAVORITE = 'F' 
    LIKE = 'L' 
    UP_VOTE = 'U' 
    DOWN_VOTE = 'D' 
    FOLLOW = 'W' 
    REPORT = 'R' 
    ACTIVITY_TYPES = (
     (FAVORITE, 'Favorite'), 
     (LIKE, 'Like'), 
     (UP_VOTE, 'Up Vote'), 
     (DOWN_VOTE, 'Down Vote'), 
     (FOLLOW, 'Follow'), 
     (REPORT, 'Report') 
    ) 

    user = models.ForeignKey(User) 
    activity_type = models.CharField(max_length=1, choices=ACTIVITY_TYPES) 
    date = models.DateTimeField(auto_now_add=True) 

    # Below the mandatory fields for generic relation 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey() 


class Entry(models.Model): 
    text = models.TextField(default='') 
    time_created = models.DateTimeField(auto_now=False, auto_now_add=True) 
    time_updated = models.DateTimeField(auto_now=True, auto_now_add=False) 
    created_by = models.ForeignKey(User, on_delete=models.CASCADE) 

    class Meta: 
     abstract = True 

class QuestionManager(models.Manager): 
    def by_topic(self, topic): 
     ... 
    def by_recent(self): 
     ... 
    def by_upvote_count(self): 
     return self.all().order_by('-upvotes')[:5]\ 
     .select_related('created_by','created_by__userprofile')\ 
     .prefetch_related('question_comments','question_comments__reply',) 


class Question(Entry): 

    objects = models.Manager() 
    get = QuestionManager() 

    activities = GenericRelation(Activity, related_query_name='questions') 

    def calculate_votes(self, type): 
     return self.activities.filter(activity_type=type).count() 

    up_votes = property(calculate_votes, 'U') 
    down_votes = property(calculate_votes, 'D') 

so, was ich versuche zu tun by_upvote_count bekommen die Top-5-upvoted zurückzukehren Artikel.

Ich fand die Count() Methode der django.db.models aber könnte es mit meinem einrichten zu arbeiten, möchte ich so etwas wie dies zu tun:

Question.objects.all().annotate(q = Count(activities__activity_type='U')).order_by('-q') 

aber offensichtlich das funktioniert nicht.

Antwort

1

Sie können etwas tun wie dieses

Model.objects.filter(activity_type='U').annotate(q_count=Count('activity_type')).order_by('-q_count')[:5] 
+0

das würde sie nach allen Aktivitäten sortieren, aber ich möchte sie nur durch die Upvotes, downvotes, likes oder ... – arianhf

+0

versuchen, die bearbeitete ans @arianhf – Exprator

+0

so, Ihre Antwort funktioniert irgendwie, aber es ist nicht genau was ich möchte. Wenn Sie Count ('activity_type') in Count ('activities__activity_type) und filter (activity_type =' U ') in filter (activities__activity_type =' U ') ändern, gibt dies jedoch alle Posts zurück, die uplotiert wurden und schließt diejenigen aus, die don Habe noch keine Verbesserung. Meine Antwort enthält beide Arten, und das ist, was ich suche. Vielen Dank für Ihre Hilfe, ich schätze es. – arianhf

1

Ok, so dass nach einer Reihe von Artikeln und einige Fragen in Stackoverflow zu lesen, die ich hier endlich eine funktionierende Antwort gefunden, es geht:

from django.db.models import Case,When 
Question.objects.all()\ 
.annotate(upvotes=Count(
    Case(
     When(activities__activity_type='U', then=1) 
    ), distinct=True 
)).order_by('-upvotes')[:5] 

Mit Case, and When können Sie Bedingungen in Ihren Abfragen machen.

Verwandte Themen