2016-01-24 5 views
0

Мои models.py выглядит следующим образом:Как я могу получить этот запрос более эффективным способом с использованием моделей Django?

class Post(models.Model): 
    user = models.ForeignKey(User, related_name = 'user_posts') 
    title = models.CharField(max_length = 140) 
    votes = models.IntegerField(default = 0) 

class Vote(models.Model): 
    user = models.ForeignKey(User, related_name = 'user_votes') 
    post = models.ForeignKey(Post, related_name = 'post_votes') 
    is_voted = models.BooleanField(default = True) 
    class Meta: 
     unique_together = [('user', 'post')] 

Позвольте мне объяснить, как моя система голосования устанавливается. Когда пользователь впервые проголосовал за сообщение, создается новый объект Vote. Пользователь может проголосовать за пост, если он проголосовал за него первым. В этом случае свойство is_voted в объекте Vote имеет значение False.

Теперь в представлении мне нужен список сообщений, которые пользователь имеет upvoted. Это означает, что существует объект Vote для комбинации post и user, AND, свойство is_voted этого объекта - True.

Вот как я в настоящее время пытается сделать это:

views.py

def user_profile(request, pk): 
    # Get user using pk 
    u = User.objects.get(pk = pk) 

    # Get a list of Votes using the user instance 
    votes = Vote.objects.filter(user = u, is_voted = True) 

    # Getting the list of posts using the votes list 
    post_list = Post.objects.none() # Generating empty list 
    for vote in votes: 
     # Adding vote.post to post_list using chaining. 
     ..... 

Это на самом деле работает, но чувствует себя очень хак-у. Есть ли способ генерировать запрос без цикла for? Я предполагаю, что могу использовать связанное имя, но я не уверен, как это сделать.

ответ

2

Я думаю, что это QuerySet должен дать все сообщения upvoted пользователем (я не пробовал, хотя):

votes = Post.objects.filter(post_votes__user=u, post_votes__is_voted=True) 

Это обратный поиск от модели, в которой указывает внешний ключ к модели, содержит его.

0

вы можете попробовать это:

post_list = [p.post for p in Vote.objects.filter(user = u, is_voted = True).select_related('post')] 
Смежные вопросы