2015-05-29 36 views
6

Próbuję utworzyć API za pomocą DRF 3.1. Zacząłem od utworzenia funkcji zarządzania przy użyciu ModelViewSet i zarejestrowania ich za pomocą DefaultRoutera. To działało idealnie, a domyślny widok główny API wygenerował odpowiednie łącza podczas przeglądania w przeglądarce. Następnie utworzyłem bardziej ograniczone widoki dla standardowych użytkowników korzystających z ReadOnlyModelViewSet, problem pojawił się, gdy próbowałem zarejestrować te ograniczone widoki z routerem, ponieważ ReadOnlyModelViewSets wydają się zastępować łącza w widoku głównym API. Generowane URL wydają się pracować po wpisaniu w przeglądarce, ale linki na widoku głównego API nie są, jak się spodziewałemDjango Rest Framework Routery z wieloma widokami

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,) 

adresy URL. py

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)) 
] 

ten wytwarza domyślne API główny widok jak ten

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

natomiast co szukam jest to

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

url 'htt: // localhost: 8000/manageunits /' jest ważna i dostępna, jeśli adres jest wpisany w przeglądarce to po prostu robi nie pojawiają się w widoku głównym API

każda pomoc będzie bardzo mile widziane

Odpowiedz

6

miałem ten sam problem i na szczęście znalazłem rozwiązanie.

Rozszerz urls.py w następujący sposób:

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

nie wiem magię za to, ale to działa na mnie :)

0

Odpowiedź z Dario Behringer jest poprawna. Ale to nie tylko magia.

Ważną częścią jest dodanie wyraźnej nazwy base_name. Zwykle DRF automatycznie generuje base_name ze zbioru zapytań. Zostało to wyjaśnione tutaj pod "base_name": www.django-rest-framework.org/api-guide/routers/. Zestaw pytań AdminUnitViewSet i UserUnitViewSet jest wewnętrznie taki sam.

Prowadzi to do tego, że później zarejestrowany ViewSet zastąpi poprzednio zarejestrowany ViewSet, gdy nie zarejestrowano jawnie nowego base_name.

Za utworzenie nazwanego adresu URL w Django odpowiada base_name. Jeśli istnieje więcej niż jeden o nazwie URL z tej samej nazwie Django będzie w zasadzie tylko za ostatni zdefiniowany: https://docs.djangoproject.com/en/1.10/topics/http/urls/#naming-url-patterns

To jest w zasadzie taki sam problem jak wyjaśniono w pytaniu Django Rest Framework with multiple Viewsets and Routers for the same object

Powiązane problemy