在prefetch_related上按日期过滤查询集

时间:2013-12-17 00:07:52

标签: django django-queryset prefetch

我需要通过比较相关对象的日期来过滤查询集,但忽略过滤器。

我恢复的模型是:

class Requerimiento(models.Model):
    nombre = models.CharField(max_length=30)
    fecha_publicacion = models.DateField(default=datetime.now)
    fecha_aprobacion = models.DateField(default=datetime.now, blank=True)
    aprobacion = models.BooleanField()
    autor = models.ForeignKey(User, null=True, blank=True)

    def __unicode__(self):
            return self.nombre

class Contexto(models.Model):
    nombre = models.CharField(max_length=30)
    requerimientos = models.ManyToManyField(Requerimiento, 
        related_name = 'contextos')

    def __unicode__(self):
            return self.nombre

class Proyecto(models.Model):
    nombre = models.CharField(max_length=30)
    cod_proyecto = models.CharField(max_length=10)
    contextos = models.ManyToManyField('Contexto', related_name = 'proyectos')
    fecha_publicacion  = models.DateField(default=datetime.now)
    autor = models.ForeignKey(User, null=True, blank=True)

查询集是:

queryset=Proyecto.objects.filter(pk=proyecto_id)\
    .prefetch_related('contextos')\
    .prefetch_related('contextos__requerimientos')\
    .filter(contextos__requerimientos__fecha_aprobacion__lte=F('fecha_publicacion'))

我做错了什么?

修改

使用调试工具栏查看以下代码中选择了proyect id 2的以下内容

requerimientos = ProyectoFilter(request.GET,
    queryset=Proyecto.objects.filter(pk=proyecto_id)
    .distinct()
    .prefetch_related('contextos')
    .prefetch_related('contextos__requerimientos')
    .filter(contextos__requerimientos__fecha_aprobacion__lte=F('fecha_publicacion')))

首先查询:

SELECT ••• FROM "sgrs_proyecto" INNER JOIN "sgrs_proyecto_contextos" 
ON ( "sgrs_proyecto"."id" = "sgrs_proyecto_contextos"."proyecto_id" ) 
INNER JOIN "sgrs_contexto" ON ( "sgrs_proyecto_contextos"."contexto_id" =  
"sgrs_contexto"."id" ) INNER JOIN "sgrs_contexto_requerimientos" 
ON ( "sgrs_contexto"."id" = "sgrs_contexto_requerimientos"."contexto_id" ) 
INNER JOIN "sgrs_requerimiento" ON ( "sgrs_contexto_requerimientos"."requerimiento_id" = "sgrs_requerimiento"."id" ) 
WHERE ("sgrs_proyecto"."id" = 2 AND "sgrs_requerimiento"."fecha_aprobacion" 
<= "sgrs_proyecto"."fecha_publicacion")

第二次查询:

SELECT ••• FROM "sgrs_contexto" INNER JOIN "sgrs_proyecto_contextos" 
ON ( "sgrs_contexto"."id" = "sgrs_proyecto_contextos"."contexto_id" ) 
WHERE "sgrs_proyecto_contextos"."proyecto_id" IN (2) 
ORDER BY "sgrs_contexto"."indice_riesgo" DESC

第三个查询:

SELECT ••• FROM "sgrs_requerimiento" INNER JOIN "sgrs_contexto_requerimientos" 
ON ( "sgrs_requerimiento"."id" = "sgrs_contexto_requerimientos"."requerimiento_id" )
WHERE "sgrs_contexto_requerimientos"."contexto_id" IN (3, 7, 6, 4, 2, 5, 1)

日期过滤器在第一个查询中,应该在第三个查询中,这是正确的吗? 如何获得正确的过滤器位置?

由于

2 个答案:

答案 0 :(得分:0)

首先,prefetch_related的使用不正确。请参阅https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related中的第一个注释。其次,您可能希望将distinct()与m2m关系上的过滤器一起使用。

您发布的查询应该为您提供所有至少有一个相关Requerimiento的Proyecto对象,其中fecha_aprobacion小于或等于其&#39;拥有fecha_aprobacion。你对查询有什么期望?你得到了什么?

答案 1 :(得分:0)

好的,终于明白了。 我从查询集中取出过滤器并在模板中进行比较。

刚刚添加以下内容:

...
{% for requerimiento in contexto.requerimientos.all %}
{% if requerimiento.fecha_aprobacion <= proyecto.fecha_publicacion %}
...

希望这有助于其他人。