Reputation: 935
I am trying to construct filter dynamically based on passed query parameters. Code below. Because the filter might end up empty, in which case all objects need to be returned, this is coming out very ugly.
Is there a way to do this cleanly? Maybe if there is a default Q that means 'do not nothing'?
def get(self, request, *args, **kwargs):
q = None
for field, value in request.GET.items():
if field not in Project._meta.fields:
continue
if q is None:
q = Q(**{'{}'.format(field): value})
else:
q &= Q(**{'{}'.format(field): value})
if q is None:
projects = get_objects_for_user(request.user, ['api.view_project', 'api.edit_project', 'api.owner_project'], any_perm=True)
else:
projects = get_objects_for_user(request.user, ['api.view_project', 'api.edit_project', 'api.owner_project'], any_perm=True).filter(q)
ser = ProjectSerializer(projects, many=True)
return Response(ser.data, status=status.HTTP_200_OK)
Upvotes: 0
Views: 46
Reputation: 124
I recommend to use django-filter:
Example of filter class:
import django_filters
class ProjectFilter(django_filters.FilterSet):
class Meta:
model = Product
fields = [
'id',
'name',
'user',
'user__username',
]
Example of view function:
def get(self, request, *args, **kwargs):
projects = get_objects_for_user(request.user, ['api.view_project', 'api.edit_project', 'api.owner_project'], any_perm=True)
projects = ProjectFilter(request.GET, queryset=projects)
ser = ProjectSerializer(projects, many=True)
return Response(ser.data, status=status.HTTP_200_OK)
Upvotes: 0