문제

Django 앱의 경우 이벤트, 등급 및 사용자가 있습니다. 등급은 외국 키를 통해 이벤트 및 사용자와 관련이 있습니다. 이벤트 목록을 표시 할 때 사용자가 이벤트의 등급을 필터링하려면 사용자가 이벤트를 평가했는지 알 수 있습니다.

만약 내가한다면:

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

(request.user.id는 현재 로그인 한 사용자의 user_id를 제공합니다) ... 그런 다음 전체 이벤트 목록이 아닌 사용자가 평가 한 이벤트 만 얻습니다.

사용자 정의 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을 사용할 필요가 없습니까?

도움이 되었습니까?

해결책

그만큼 filter 방법은 지정된 기준에 따라 반환되는 객체를 필터링하는 것이므로 여기에서 원하는 것이 아닙니다. 한 가지 옵션은 주어진 모든 등급을 검색하기 위해 두 번째 쿼리를 수행하는 것입니다. Event 전류에 대한 객체 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 %}

다른 팁

S.Lott의 제안 외에도 select_related ()를 사용하여 데이터베이스 쿼리 수를 제한하는 것을 고려할 수 있습니다. 그렇지 않으면 템플릿이 각 이벤트의 루프를 통과하는 쿼리를 수행합니다.

Event.objects.all().select_related(depth=1)

깊이 매개 변수는 필요하지 않지만 다른 모델에 추가적인 외부 키가있는 경우 조인 수가 제한됩니다.

Django를 최대한 활용하려면 가입을 피해야합니다.

"왼쪽 외부 조인"은 실제로 선택적 관계가있는 객체 목록입니다.

단순히 이벤트 목록입니다. Event.objects.all(). 일부 이벤트 객체에는 등급이 있으며 일부는 그렇지 않습니다.

당신은 당신의 관점에서 이벤트 목록을 얻습니다. 템플릿의 선택적 관계를 처리합니다.

{% for e in event_list %}
    {{ e }}
    {% if e.rating_set.all %}{{ e.rating_set }}{% endif %}
{% endfor %}

점프 포인트입니다.

나는 당신이 이런 일을해야한다고 생각합니다.

events=Event.objects.filter(rating__user=request.user.id)
ratings='(select rating from ratings where user_id=%d and event_id=event_events.id '%request.user.id
events=events.extra(select={'rating':ratings})
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top