Wednesday, June 14, 2017

RE: ordering queries based on most upvotes

It is difficult to follow your formatting, so I updated it below.

 

I would always avoid using GenericForeignKey().  That's my own personal preference, but it doesn't even seem like you need it in your situation.  You could just have a ForeignKey or ManyToMany directly to Activity.

 

Read more about annotation and aggregation:

https://docs.djangoproject.com/en/1.11/topics/db/aggregation/

 

This will filter only those questions that do have up votes:

Question.objects.filter(activities__activity_type=Activity.UP_VOTE).annotate(upvotes=Count('activities')).order_by('upvotes')

 

 

From: django-users@googlegroups.com [mailto:django-users@googlegroups.com] On Behalf Of Arian Hedayati Far
Sent: Wednesday, June 14, 2017 6:51 AM
To: Django users
Subject: ordering queries based on most upvotes

 

I want to order my query based on the number of upvotes but I can't figure out how to do it. It seems way too complex! ( btw am I over-complicating things?)

so here is my 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, what I'm trying to do is to get by_upvote_count to return the top 5 upvoted items.

I found the Count() method of the django.db.models but could get it to work with my set up, I want to do something like this:

.Count(activities__activity_type='U') 
 

but obviously this doesn't work.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/3121284e-12af-4e43-a35f-d1f39e8a0c15%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment