2015-05-29 2 views
6

Я пытаюсь создать API с использованием DRF 3.1. Я начал с создания функций manangement с помощью ModelViewSet и регистрации их с помощью DefaultRouter. Это отлично работало, и в корневом представлении API по умолчанию были созданы соответствующие ссылки при просмотре в браузере. Затем я создал более ограниченные виды просмотров для стандартных пользователей с помощью ReadOnlyModelViewSet, возникла проблема, когда я попытался зарегистрировать эти ограниченные виды с помощью маршрутизатора, поскольку ReadOnlyModelViewSets, похоже, перезаписывают ссылки в корневом представлении API. Сформированные URLs появляются работать при вводе в браузере, но ссылки на корневой зрения API не как я ожидалМаршрутизаторы Django Rest Framework с несколькими видами.

serializers.py

class AdminUnitSerializer(serializers.HyperlinkedModelSerializer): 
''' 
model serializer for admin users containing all fields 

''' 

url = HyperlinkedIdentityField(view_name='unit-detail') 

class Meta: 
    model = Unit 
    fields = ('url', 'id', 'name', 'symbol', 'converters_from', 'converters_to') 

class UserUnitSerializer(serializers.HyperlinkedModelSerializer): 
''' 
model serializer for standard users containing restricted set of fields 

''' 

url = HyperlinkedIdentityField(view_name='unit-detail') 

class Meta: 
    model = Unit 
    fields = ('url', 'id', 'name', 'symbol') 

views.py

class AdminUnitViewSet(viewsets.ModelViewSet): 
''' 
simple viewset providing CRUD operations on unit objects 

''' 

queryset = models.Unit.objects.all() 
serializer_class = serializers.AdminUnitSerializer 
permission_classes = (permissions.IsAdminUser,) 

class UserUnitViewSet(viewsets.ReadOnlyModelViewSet): 
''' 
read only view set providing list and detail views for unit objects 

''' 

queryset = models.Unit.objects.all() 
serializer_class = serializers.UserUnitSerializer 
permission_classes(permissions.IsAuthenticated,) 

URLs. ру

router.register(r'manangeunits', views.AdminUnitViewSet) 
router.register(r'readunits', views.UserUnitViewSet) 

urlpatterns = [ 
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 
url(r'^rest-auth/', include('rest_auth.urls')), 
url(r'^', include(router.urls)) 
] 

это производит по умолчанию API вид корня, как этот

{ 
"manangeunits": "http://localhost:8000/readunits/", 
"readunits": "http://localhost:8000/readunits/", 
} 

а то, что я ищу это

{ 
"manangeunits": "htt://localhost:8000/manageunits/", 
"readunits": "htt://localhost:8000/readunits/", 
} 

URL-адрес «НТТ: // локальный: 8000/manageunits /» является действительным и доступным, когда адрес набран в браузере он просто делает не появляются на представлении корневой API

любая помощь будет высоко оценен

ответ

6

Я была такая же проблема и, к счастью, нашли решение.

Расширьте urls.py следующим образом:

router.register(r'manangeunits', views.AdminUnitViewSet, base_name='manangeunits') 
router.register(r'readunits', views.UserUnitViewSet, base_name='readunits') 

Я не знаю магию позади, но это работает для меня :)

0

Ответ от Dario Behringer правильно. Но это не просто волшебство.

Важной частью является добавление явного base_name. Обычно DRF автоматически генерирует base_name из вашего набора запросов. Это объясняется здесь под «base_name»: www.django-rest-framework.org/api-guide/routers/. Номер запроса AdminUnitViewSet и UserUnitViewSet тот же внутренний.

Это приводит к тому, что более поздний зарегистрированный ViewSet перезапишет прежнего зарегистрированного ViewSet, если нет явного нового зарегистрированного base_name.

base_name несет ответственность за создание именованного URL-адреса в Django. Если есть больше чем один названный URL с тем же именем Django будет в основном только рассмотреть последний определяется: https://docs.djangoproject.com/en/1.10/topics/http/urls/#naming-url-patterns

Это в основном та же проблема, как описано в вопросе Django Rest Framework with multiple Viewsets and Routers for the same object

Смежные вопросы