Tenemos los siguientes modelos:
class Publisher(models.Model): name = models.CharField(max_length=32) local_name = models.CharField(max_length=32) url_pattern = models.CharField(max_length=128) enabled = models.BooleanField(default=True) home_page = models.BooleanField(default=False) category = models.ForeignKey(NewspaperCategory, null=True) class Newspaper(models.Model): class Meta: unique_together = ("publisher", "date") ordering = ("-date",) publisher = models.ForeignKey(Publisher) image = models.ImageField(upload_to=newspaper_upload_to) thumbnail = models.ImageField(upload_to=newspaper_thumbnail_upload_to) date = models.DateField() Tengo un APIView (marco de descanso de Django) y hay varios parámetros de consulta diferentes que filtran la salida de la API. Me gustaría tener un parámetro de consulta "más reciente" que enumere solo la última versión de cada editor. Además, necesito poder filtrar y dividir más ese QuerySet antes de evaluarlo.
Pero el resultado de la consulta debería ser que las instancias del periódico no se dict para que pueda enviarlas a mi serializador. Mi vista se ve así en este momento:
class Newspapers(APIView): def get(self, request): queryset = models.Newspaper.objects.filter(deleted=False).prefetch_related('publisher') if "latest" in request.GET: # doing something here with queryset if "publisher_id" in request.GET: queryset = queryset.filter(publisher_id=request.GET['publisher_id']) if "category" in request.GET: queryset = queryset.filter(publisher__category_id=request.GET['category']) if "before" in request.GET: queryset = queryset.filter(date__lt=request.GET['before']) if "after" in request.GET: queryset = queryset.filter(date__gte=request.GET['after']) if "home_page" in request.GET: queryset = queryset.filter(publisher__home_page=request.GET['home_page'].lower() == 'true') queryset = queryset.order_by('-date', 'publisher__order') return PagingResponse( request, serializers.NewspaperVersionSerializer, query=queryset, identifier_name='date' )Podemos hacer esto con dos consultas:
if "latest" in request.GET: latest_ids = list( # <-- first query queryset.order_by('id') .values('publisher_id') .annotate(id=Max('id')) .values_list('id', flat=True) ) queryset = queryset.filter(id__in=latest_ids) # <-- second queryla primera consulta obtiene una lista del último grupo de periódicos por editor, y la segunda consulta obtiene un conjunto de consultas de esos periódicos para filtrar, dividir y...