18👍
You can create custom filter for slipdate, netweight
that will evaluate and filter this fields in db. For this you can use conditional expressions and F expression
from django.db.models import F, Case, When
class WeightSlipFilter(FilterSet):
slipdate = DateTimeFilter(method='filter_slipdate')
netweight = NumberFilter(method='filter_netweight')
class Meta:
model = WeightSlip
fields = ('slipdate', 'netweight', 'vehicle')
def filter_netweight(self, queryset, value):
if value:
queryset = queryset.annotate(netweight=F('grossweight') - F('tareweight')).filter(netweight=value)
return queryset
def filter_slipdate(self, queryset, value):
if value:
queryset = queryset.annotate(slipdate=Case(When(grossdate__gt=F('taredate'), then=F('grossdate')), default=F('taredate')).filter(slipdate=value)
return queryset
4👍
Note that if you’re using the latest version of django-filter, Filter.method
takes 4 arguments, like so:
def filter_slipdate(self, queryset, name, value):
if value:
queryset = queryset.annotate(slipdate=Case(When(grossdate__gt=F('taredate'), then=F('grossdate')), default=F('taredate')).filter(slipdate=value)
return queryset
“`
0👍
Extending the answer further. With the latest django and drf version one might experience an exception like this.
Exception
File "/home/USER/.env/drf3/lib64/python3.7/site-packages/django/db/models/query.py", line 76, in iter
setattr(obj, attr_name, row[col_pos])
AttributeError: can’t set attribute
Versions Used: Django==3.1
djangorestframework==3.11.1
django-filter==2.3.0
The solution that worked for me is this where slipdate and netweight requires model name to be used in the queryset…
def filter_slipdate(self, queryset, name, value):
if value:
queryset = queryset.annotate(WeightSlip__slipdate=Case(When(grossdate__gt=F('taredate'), then=F('grossdate')), default=F('taredate'))).filter(WeightSlip__slipdate=value)
return queryset
def filter_netweight(self, queryset, name, value):
if value:
queryset = queryset.annotate(WeightSlip__netweight=F('grossweight') - F('tareweight')).filter(WeightSlip__netweight=value)
return queryset
return queryset
- Django Model " has more than one ForeignKey to "
- Django and service workers – serve "sw.js" at application's root url
- Django – OperationalError: (2006, 'MySQL server has gone away')