Django Rest Framework with multiple view modes and routers for the same object

I'm having trouble defining different sets of views for the same object using the Django Rest Framework. Below is a minimal example to reproduce a problem based on Quickstart DRF. I am using python 3.5 and latest DRF.

tutorial /Quickstart/serializers.py

from django.contrib.auth.models import User from rest_framework import serializers class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('url', 'username', 'email') class UserMinimalSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('url', 'username') 

tutorial /Quickstart/views.py

 from django.contrib.auth.models import User from rest_framework import viewsets from tutorial.quickstart.serializers import UserSerializer, UserMinimalSerializer class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all().order_by('-date_joined') serializer_class = UserSerializer class UserMinimalViewSet(viewsets.ModelViewSet): queryset = User.objects.all().order_by('-date_joined') serializer_class = UserMinimalSerializer 

tutorial /urls.py

 from django.conf.urls import url, include from rest_framework import routers from tutorial.quickstart import views router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) router.register(r'users-minimal', views.UserMinimalViewSet) urlpatterns = [ url(r'^', include(router.urls)) ] 

When you start the server and get the root directory, you will get:

 HTTP 200 OK Allow: GET, HEAD, OPTIONS Content-Type: application/json Vary: Accept { "users": "http://127.0.0.1:8000/users-minimal/", "users-minimal": "http://127.0.0.1:8000/users-minimal/" } 

Note that both users and users-minimal point to .../users-minimal/ .

Also, when accessing http://HOST:PORT/users/ you get:

 HTTP 200 OK Allow: GET, POST, OPTIONS Content-Type: application/json Vary: Accept { "count": 2, "next": null, "previous": null, "results": [ { "url": "http://127.0.0.1:8000/users-minimal/2/", "username": "user2", "email": " user2@users.com " }, { "url": "http://127.0.0.1:8000/users-minimal/1/", "username": "user1, "email": " user1@users.com " } ] } 

Note that the URLs point to .../users-minimal/ .

Final note: my question is somewhat similar to this one , but the proposed solution did not work for me, and did not suggest why it should work in the first place.

+3
source share
1 answer

Short answer: you need to add the base_name parameter to your route in users-minimal :

 router = routers.DefaultRouter() router.register(r'users', UserViewSet) router.register(r'users-minimal', UserMinimalViewSet, base_name='usersminimal') 

Usually DRF automatically generates base_name from your request. This is explained here under "base_name": www.django-rest-framework.org/api-guide/routers/

Your two views use the same set of queries as the original same base_name . This leads to the problems you saw that a later registered ViewSet will rewrite routes from a previously registered ViewSet. You can see this in action when you reorder the router.register in your example.

You can see the base names of your routes when checking the code directly in the shell:

 from rest_framework import routers from tutorial.quickstart import views router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) router.register(r'users-minimal', views.UserMinimalViewSet) > routers.urls [<RegexURLPattern user-list ^minimal/$>, <RegexURLPattern user-list ^minimal\.(?P<format>[a-z0-9]+)/?$>, <RegexURLPattern user-detail ^minimal/(?P<pk>[^/.]+)/$>, <RegexURLPattern user-detail ^minimal/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, <RegexURLPattern user-list ^users/$>, <RegexURLPattern user-list ^users\.(?P<format>[a-z0-9]+)/?$>, <RegexURLPattern user-detail ^users/(?P<pk>[^/.]+)/$>, <RegexURLPattern user-detail ^users/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, <RegexURLPattern api-root ^$>, <RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>] 
+4
source

Source: https://habr.com/ru/post/988181/


All Articles