6 votes

Django Rest Framework avec plusieurs Viewsets et Routers pour le même objet

J'ai des difficultés à définir différents jeux de vues pour le même objet en utilisant Django Rest Framework. Voici un exemple minimal pour reproduire le problème, basé sur DRF Quickstart. J'utilise python 3.5 et la dernière version de 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))
]

Lorsque l'on exécute le serveur et que l'on obtient la racine, on se retrouve avec :

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/"
}

Noter les deux users y users-minimal pointer vers .../users-minimal/ .

De même, lors de l'accès aux http://HOST:PORT/users/ vous obtenez :

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"
        }
    ]
}

Notez que les adresses URL pointent vers .../users-minimal/ .

Note finale : ma question est quelque peu similaire à celui-ci La solution proposée n'a pas fonctionné pour moi, et il n'a pas non plus été expliqué pourquoi elle devrait fonctionner.

6voto

DanEEStar Points 1531

Réponse courte : Vous devez ajouter le basename à votre route vers users-minimal :

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

Normalement, le DRF génère un basename automatiquement à partir de votre queryset . Ceci est expliqué dans le Documentation sur les routeurs DRF , rechercher basename .

Vos deux Viewset utilisent les mêmes queryset ils ont donc initialement les mêmes basename . Cela conduit aux problèmes que vous avez constatés, à savoir que les enregistrements les plus tardifs ne sont pas pris en compte dans le calcul de l'impôt sur le revenu. ViewSet remplacera les itinéraires de l'ancien registre ViewSet . Vous pouvez voir cela à l'œuvre lorsque vous modifiez l'ordre de l'élément router.register dans votre exemple.

Vous pouvez voir les noms de base de vos routes lorsque vous testez le code directement dans le 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]+)/?$>]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X