There are products, with some master data, like SKU and some variations of
that product in different contexts (profiles) like name and description.
{{{
class Product:
sku = models.CharField()
class ProductProfileGroup:
is_default = models.BooleanField()
class ProductProfile:
group = models.ForeignKey(to='ProductProfileGroup',
related_name='profiles')
product = models.ForeignKey(to='Product', related_name='profiles')
name = models.CharField()
description = models.CharField()
}}}
If I were to retrieve all information of a product, with a specific
profile group, I have to write the below code:
{{{
Product.objects.annotate(
name=F('profiles__name'),
description=F('profiles__description'),
).filter(profiles__group_id=1)
"""
select product.sku, product_profile.name, product_profile.description
from product
join product_profile on product_profile.product_id = product.id
where product_profile.group_id = 1
"""
}}}
This is a bit cumbersome, hard to read because of those plurals. My
suggested approach would be something like:
{{{
def get_selected_profile():
# maybe use settings, or some request context like
https://pypi.org/project/django-currentuser/
return
Q(product_profile_group_id=get_current_user().preferred_product_profile_group_id)
class ProductProfile:
product = models.ForeignKey(to='Product', related_name='profiles',
related_queries={
'default_profile': Q(is_default=True),
'selected_profile': get_selected_profile,
})
# the same annotation, much more readable:
Product.objects.annotate(
name=F('default_profile__name'),
)
"""
select product.sku, product_profile.name, product_profile.description
from product
join product_profile on product_profile.product_id = product.id and
product_profile.is_default is true
"""
Product.objects.annotate(
name=F('selected_profile__name'),
)
"""
select product.sku, product_profile.name, product_profile.description
from product
join product_profile on product_profile.product_id = product.id and
product_profile.product_profile_group_id = 1
"""
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/32423>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => wontfix
Comment:
Thanks for this report, however I don't a reason to add a new mechanism
for this. For example, you can achieve the same with
[https://docs.djangoproject.com/en/dev/topics/db/managers/#adding-extra-
manager-methods extra methods in the manager].
Also, you'll reach a wider audience if you write to the
DevelopersMailingList about your ideas.
--
Ticket URL: <https://code.djangoproject.com/ticket/32423#comment:1>