amusingalan
amusingalan

Reputation: 35

Best practice way of adding querystrings in django rest framework

I need to add querystrings to django rest framework but so far all the information I've read either doesn't work for me or just doesn't make sense for something simple. So I'm wondering, what's the "official" way or best practice of doing things?

The endpoint I'm using is /account?user_id=1. My urls.py is set up as follows:

router = routers.SimpleRouter(trailing_slash=False)
router.register(r'account', view.AccountViewSet)
urlpatterns = [
    path('', include(router.urls)),
]

These are the options I've explored:

  1. Using search filters:

    In AccountViewSet, I've set the following:

    from rest_framework.filters import SearchFilter
    .
    .
    .
    class AccountViewSet(mixins.CreateModelMixin,
                        mixins.RetrieveModelMixin,
                        mixins.UpdateModelMixin,
                        viewsets.GenericViewSet):
      filter_backends = (SearchFilter, )
      search_fields = ['user_id']
    .
    .
    .
    

    With this I get a 405, Method \"GET\" not allowed.

  2. Add router.register(r'', view.AccountViewSet, basename='account) to urls.py then override either get_queryset or retrieve() which then means I have to add logic to handle two use cases, getting an account using path parameters and getting an account with a user_id in the query string.

  3. Add a custom action with regex pattern. With this, I'd still have router.register(r'', view.AccountViewSet, basename='account). Then in my viewset I have:

    @action(detail=False, url_path='(?P<user_id>[^/.]+)')
        def get_user_id(self, request, user_id=None):
            .
            .
    

    This would also work, but the problem I'm getting (which doesn't seem right) is that when I hit my endpoint /account?user_id=1, the user_id parameter gets set as "account" and not 1

So what really is the best practice to handle this?

Upvotes: 0

Views: 1182

Answers (1)

AviKKi
AviKKi

Reputation: 1214

Below are the mixins and their respective url + http method

| Mixin              | Endpoint       | Method |
|--------------------|----------------|--------|
| CreateModelMixin   | /account/      | POST   |
| RetrieveModelMixin | /account/<id>/ | GET    |
| UpdateModelMixin   | /account/<id>/ | POST   |
| ListModelMixin     | /account/      | GET    |

You are using top 3 mixins and calling the endpoint for ListModelMixin, just add it as parent class as shown below and you are good to go.

class AccountViewSet(mixins.ListModelMixin,
                    mixins.CreateModelMixin,
                    mixins.RetrieveModelMixin,
                    mixins.UpdateModelMixin,
                    viewsets.GenericViewSet,
):

Rest Framework docs reference on mixins

Search filter reference you may find it useful.

Upvotes: 1

Related Questions