如何使用Django的数据库API构建嵌套查询

时间:2017-05-31 17:23:03

标签: python django postgresql django-queryset

我需要在Django中创建以下PostgreSQL语句的查询集。

SELECT * FROM 
(
SELECT DISTINCT ON("atech_cars".
    "model")
"atech_cars".
"make", "atech_cars".
"model", "atech_cars".
"trim"
FROM "atech_cars"
WHERE(UPPER("atech_cars".
        "make"::text) = UPPER('Ford') AND "atech_cars".
    "model"
    IN(SELECT U0.
        "char_value"
        AS Col1 FROM "clf_atech_filter_cache"
        U0 WHERE U0.
        "filter_id" = 7))
) Sub 
ORDER BY 
CASE WHEN ("model" = 'xD') THEN 0 
WHEN ("model" = 'Cayenne') THEN 1 
WHEN ("model" = 'Elantra') THEN 297 ELSE NULL END ASC

这是我想在查询集末尾生成的查询。

我已经创建了以下语句的查询集。

SELECT DISTINCT ON("atech_cars".
    "model")
"atech_cars".
"make", "atech_cars".
"model", "atech_cars".
"trim"
FROM "atech_cars"
WHERE(UPPER("atech_cars".
        "make"::text) = UPPER('Ford') AND "atech_cars".
    "model"
    IN(SELECT U0.
        "char_value"
        AS Col1 FROM "clf_atech_filter_cache"
        U0 WHERE U0.
        "filter_id" = 7))

所以最终,我正在寻找以下语句的queryset。

SELECT * FROM 
(
<Queryset>
) Sub 
ORDER BY 
CASE WHEN ("model" = 'xD') THEN 0 
WHEN ("model" = 'Cayenne') THEN 1 
WHEN ("model" = 'Elantra') THEN 297 ELSE NULL END ASC

这是我创建的django查询集,但它无效。

class ATechCarModelFilter(Filter):

    def filter(self, qs, value):
        # trim filter_id = 9 in atech_filter
        trims = ClfCacheModel.objects.filter(filter_id = 9).values_list('char_value', flat=True).order_by("counter")
        preserved = Case(*[When(trim=trim, then=pos) for pos, trim in enumerate(trims)])
        return qs.filter(model__iexact = value).filter(trim__in=trims).order_by(preserved)

这里,qs指的是BModel的查询集

如何构建我已有的查询对象?

我做错了什么?

根据要求,这是模型

class BModal(models.Model):
    char_value = models.CharField(max_length=2048, blank=True, null=True)
    counter = models.IntegerField()

    class Meta:
        managed = False
        db_table = 'filter_cache'

class AModel(models.Model):
    make = models.CharField(max_length=200, primary_key=True)
    model = models.CharField(max_length=200, primary_key=True)
    trim = models.CharField(max_length=200)

    class Meta:
        managed = False
        db_table = 'amodel'

这就是我想要的。

1)AModel和BModel现在没有关系。

2)从AModel表中获取模型列表,然后根据该列表的顺序,我想按照BModel中的列表顺序进行排序。

3)之后,我想删除带有distint的重复项目(&#34; model&#34;)

使用注释更新了ATechCarMakeFilter():

class ATechCarMakeFilter(Filter):
    def filter(self, qs, value):
      # model filter_id = 7 in atech_filter
      models = ClfCacheModel.objects.filter(filter_id = 7).values_list('char_value', flat=True).order_by("counter")
      preserved = Case(*[When(model=model, then=pos) for pos, model in enumerate(models)], default=None, output_field=IntegerField())
      qs = qs.filter(make__iexact = value).filter(model__in=models).distinct("model")        
      return qs.annotate(ordering=preserved).order_by("-ordering")  

1 个答案:

答案 0 :(得分:1)

好的,我想我明白你在这里发生了什么。您可以使用您要查找的case语句对您的queryset进行批注,然后按

进行排序
from django.db.models import Count, Case, When, IntegerField

class ATechCarModelFilter(Filter):
     def filter(self, qs, value):
        qs = ... 
        ...  # previous filters
        qs.annotate(
            ordering=Case(
                When(model='xD', then=0),
                When(model='Cayenne', then=1),
                When(model='Elantra', then=297),
                default=None,
                output_field=IntegerField()
            )
        ).order_by('-ordering')