I need to create a queryset in Django of the following PostgreSQL statement.
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
This is the query I want to generate at the end with queryset.
I've already created a query set of the following statement.
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))
so eventually, I'm looking for queryset for the following statement.
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
Here is the django queryset I've created, but it's not working.
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)
here, qs refers to queryset of BModel
How do I build on the query object I already have?
What am I doing wrong?
Here is the models as requested.
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'
Here is what I want.
1) AModel and BModel is not related, right now.
2) Get the list of models from AModel table and then based on the order of that list, I wanna order in the order of list in BModel.
3) After that, I wanna remove duplicated items with distint("model")
Updated ATechCarMakeFilter() with annotate:
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")