Django - 过滤相关对象 [英] Django - filtering on related objects

查看:21
本文介绍了Django - 过滤相关对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的 Django 应用程序,我有事件、评级和用户.评级通过外键与事件和用户相关.在显示事件列表时,我想通过 user_id 过滤事件的评级,以便我知道用户是否对事件进行了评级.

For my Django app I have Events, Ratings, and Users. Ratings are related to Events and Users through a foreign keys. When displaying a list of Events I want to filter the ratings of the Event by a user_id so I know if an event has been rated by the user.

如果我这样做:

event_list = Event.objects.filter(rating__user=request.user.id)

(request.user.id 给出当前登录用户的 user_id) ...然后我只得到用户评分的事件,而不是整个事件列表.

(request.user.id gives the user_id of the current logged in user) ...then I only get the events that are rated by the user and not the entire list of events.

我需要的可以通过自定义SQL生成:

What I need can be generated through the custom SQL:

SELECT *
FROM `events_event`
LEFT OUTER JOIN (
  SELECT *
  FROM `events_rating`
  WHERE user_id = ##
  ) AS temp 
ON events_event.id = temp.user_id

有没有更简单的方法让我不必使用自定义 SQL?

Is there an easier way so I don't have to use custom SQL?

推荐答案

filter 方法是根据指定的条件过滤返回哪些对象,所以这里不是你想要的.一种选择是执行第二次查询以检索当前 User 的给定 Event 对象的所有评级.

The filter method is for filtering which objects are returned based on the specified criteria, so it's not what you want here. One option is to do a second query to retrieve all ratings for given Event objects for the current User.

型号:

import collections

from django.db import models

class RatingManager(models.Manager):
    def get_for_user(self, events, user):
        ratings = self.filter(event__in=[event.id for event in events],
                              user=user)
        rating_dict = collections.defaultdict(lambda: None)
        for rating in ratings:
            rating_dict[rating.event_id] = rating
        return rating_dict

class Rating(models.Model):
    # ...
    objects = RatingManager()

查看:

events = Event.objects.all()
user_ratings = Rating.objects.get_for_user(events, request.user)
context = {
    'events': [(event, user_ratings[event.id]) for event in events],
}

模板:

{% for event, user_rating in events %}
  {% if user_rating %} ... {% endif %}
{% endfor %}

这篇关于Django - 过滤相关对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆