variable urls template ifequal examples bootstrap django filter

urls - Django: filtrado en objetos relacionados



django views (4)

Además de la sugerencia de S.Lott, puede considerar el uso de select_related () para limitar el número de consultas a la base de datos; de lo contrario, su plantilla hará una consulta sobre el pase de cada evento a través del ciclo.

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

El parámetro de profundidad no es obligatorio, pero si sus otros modelos tienen claves externas adicionales, limitará el número de combinaciones.

Para mi aplicación Django, tengo Eventos, Calificaciones y Usuarios. Las clasificaciones se relacionan con Eventos y Usuarios a través de claves externas. Al mostrar una lista de eventos, deseo filtrar las calificaciones del evento por un user_id para saber si un evento ha sido calificado por el usuario.

Si lo hago:

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

(request.user.id da el user_id del usuario que ha iniciado sesión actualmente) ... entonces solo obtengo los eventos calificados por el usuario y no la lista completa de eventos.

Lo que necesito se puede generar a través del SQL personalizado:

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

¿Hay una manera más fácil así que no tengo que usar SQL personalizado?


El método de filter es para filtrar qué objetos se devuelven según los criterios especificados, por lo que no es lo que quiere aquí. Una opción es hacer una segunda consulta para recuperar todas las clasificaciones para objetos de Event dados para el User actual.

Modelos:

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()

Ver:

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], }

Modelo:

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


Creo que tienes que hacer algo como esto.

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})


Para hacer el mejor uso de Django, debes evitar intentar uniones.

Una "combinación externa izquierda" es en realidad una lista de objetos con relaciones opcionales.

Es simplemente una lista de Eventos, Event.objects.all() . Algunos objetos de Evento tienen una calificación, otros no.

Obtiene la lista de Eventos en su opinión. Usted maneja las relaciones opcionales en su plantilla.

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

es un punto de partida.