1

I've an endpoint that accepts either the uuid or the phonenumber of the user

url(r'^(?P<uuid>[0-9A-Fa-f+-]+)/$', view_name.as_view()),

Now, I've a queryset that filter accordingly. Here it is.

class UserDetails(RetrieveUpdateAPIView):
    serializer_class = UserSerializer
    lookup_field = 'uuid'

    def get_queryset(self):
        """
        Over-riding queryset.

        Filter user based on the user_id(Works for both msisdn & uuid).
        """
        msisdn_or_uuid = self.kwargs[self.lookup_field]
        queryset = Users.objects
        try:  # checking if the forwarded param is user_id or msisdn.
            UUID(msisdn_or_uuid)
            instance = queryset.filter(uuid=msisdn_or_uuid)
        except ValueError:
            instance = queryset.filter(msisdn=msisdn_or_uuid)
            print instance # prints a queryset. But returns 404.
        return instance

Now the problem is whenever phone number is passed, it returns 404 not found. But the objects clearly exist.

Is there any setting in DRF that filters on two or more fields simultaneously without over-riding the get_queryset.??

I found a related question, but couldn't make it work. Where am I going wrong?

UPDATE

This is what I've tried. It works. But would like to hear better solutions(if any)

class FilterByUuidMsisdnMixin(object):
    """
    Mixin to filter by multiple lookup_fields.

    Apply this mixin to any view or viewset to get multiple field (only uuid &
    msisdn) filtering, instead of the default single field filtering.
    """

    def get_object(self):
        """Over-riding get_object."""
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        field = self.kwargs.get(self.lookup_field)
        filters = {}
        try:  # checking if the forwarded param is user_id or msisdn.
            UUID(field)
            filters['uuid'] = field  # filter by uuid.
        except ValueError:
            filters['msisdn'] = field  # filter by msisdn.

        obj = get_object_or_404(queryset, **filters)  # Lookup the object
        self.check_object_permissions(self.request, obj)  # check permissions.
        return obj
Praful Bagai
  • 16,684
  • 50
  • 136
  • 267

0 Answers0