taxes = JoinedSubquery(Tax.objects.all())
products = Product.objects.all()
# .join is probably better be placed in QuerySet class, so it will be products.join(taxes, ...)
products_with_taxes = taxes.join(
products,
join_type=LOUTER, # Optional argument, LOUTER by default
country=taxes.F('product_country'), # Also Q objects are supported
type=taxes.F('product_type')
).annotate(
tax_amount=taxes.F('amount') # .join() and .annotate() calls needn't to be chained
)
qs.attach(q1=some_qs).filter(a=F('q1__b'))It is my opinion that the Subquery object that already exists in Django should act as a CTE.
There is a ticket for this feature already:
https://code.djangoproject.com/ticket/28919
I have noticed that several developers have proposed several different patches for CTEs, but I do not know why they have never made it in. Perhaps someone with more knowledge on that matter can help.
--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
django-develop...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/8c41e40f-876c-46c0-9e24-09e8c72592ce%40googlegroups.com.
Product.objects.create(name='Pizza', country='USA', type='FOOD')
Tax.objects.create(name='USA Food Tax', amount=10, product_country='USA', product_type='FOOD')
taxes = Tax.objects.filter(
product_type=OuterRef('type'),
product_country=OuterRef('country')
)
products = Product.objects.annotate(taxes=Subquery(taxes, join=True, join_type=LOUTER))
product = products.annotate(tax=F('taxes__amount'), tax_name=F('taxes__name'))
SELECT "core_product"."id", "core_product"."name", "core_product"."country", "core_product"."type", "taxes"."__col3" AS "tax", "taxes"."__col4" AS "tax_name"
FROM "core_product"
LEFT OUTER JOIN
(
SELECT
"core_tax"."id", "core_tax"."product_country", "core_tax"."product_type", "core_tax"."name", "core_tax"."amount",
"core_tax"."product_country" AS "__col1", "core_tax"."product_type" AS "__col2", "core_tax"."amount" AS "__col3", "core_tax"."name" AS "__col4"
FROM "core_tax"
) "taxes" ON ("taxes"."__col1" = ("core_product"."country") AND "taxes"."__col2" = ("core_product"."type"))
Product.objects.annotate(taxes=Subquery(taxes, join=True, join_type=LOUTER))