| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- from django.db.models import Count, OuterRef, Subquery
- from django.db.models.functions import Coalesce
- __all__ = (
- 'count_related',
- 'dict_to_filter_params',
- )
- def count_related(model, field):
- """
- Return a Subquery suitable for annotating a child object count.
- """
- subquery = Subquery(
- model.objects.filter(
- **{field: OuterRef('pk')}
- ).order_by().values(
- field
- ).annotate(
- c=Count('*')
- ).values('c')
- )
- return Coalesce(subquery, 0)
- def dict_to_filter_params(d, prefix=''):
- """
- Translate a dictionary of attributes to a nested set of parameters suitable for QuerySet filtering. For example:
- {
- "name": "Foo",
- "rack": {
- "facility_id": "R101"
- }
- }
- Becomes:
- {
- "name": "Foo",
- "rack__facility_id": "R101"
- }
- And can be employed as filter parameters:
- Device.objects.filter(**dict_to_filter(attrs_dict))
- """
- params = {}
- for key, val in d.items():
- k = prefix + key
- if isinstance(val, dict):
- params.update(dict_to_filter_params(val, k + '__'))
- else:
- params[k] = val
- return params
|