You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django 2.0 + DRF 3.8中正确配置并注册ViewSet路由

Hey there! Let's break down how to smoothly switch from class-based views with explicit URLs to using DRF ViewSets and routers for automatic URL generation in your DRF 3.8 + Django 2.0 setup. I've done this plenty of times, so let's walk through it step by step.

Step 1: Convert Your Class-Based Views to a ViewSet

First, you'll want to replace your existing class-based views (like ListAPIView, RetrieveAPIView, etc.) with a ViewSet. DRF provides pre-built ViewSets that bundle common actions together to save you time.

For example, if you're working with a UserProfile model, update your UserProfile/views.py like this:

from rest_framework import viewsets
from .models import UserProfile
from .serializers import UserProfileSerializer

# ModelViewSet gives you all CRUD actions: list, create, retrieve, update, partial_update, destroy
class UserProfileViewSet(viewsets.ModelViewSet):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer

If you only need read-only access (no create/update/delete), use viewsets.ReadOnlyModelViewSet instead—it includes just list and retrieve actions.

Step 2: Set Up a Router in Your App's URLs

Next, let's configure the router in UserProfile/urls.py to auto-generate URLs for your ViewSet. DRF's DefaultRouter handles all the URL mapping automatically, so you don't have to write each URL pattern manually.

Here's how to update your app's urls.py:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserProfileViewSet

# Initialize the router
router = DefaultRouter()
# Register your ViewSet: the first argument is the base path, basename is used for reverse lookups
router.register(r'', UserProfileViewSet, basename='userprofile')

urlpatterns = [
    # Include all URLs generated by the router
    path('', include(router.urls)),
]

With this setup, the router will automatically create these URLs:

  • GET /userprofile/ → Lists all user profiles (list action)
  • POST /userprofile/ → Creates a new user profile (create action)
  • GET /userprofile/<pk>/ → Retrieves a single user profile (retrieve action)
  • PUT /userprofile/<pk>/ → Updates a user profile (update action)
  • PATCH /userprofile/<pk>/ → Partially updates a user profile (partial_update action)
  • DELETE /userprofile/<pk>/ → Deletes a user profile (destroy action)

Want Custom Actions?

If you need to add custom endpoints (like a stats endpoint for a user), use the @action decorator on your ViewSet:

from rest_framework.decorators import action
from rest_framework.response import Response

class UserProfileViewSet(viewsets.ModelViewSet):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer

    # detail=True means this action applies to a single instance (needs a pk)
    @action(detail=True, methods=['get'])
    def stats(self, request, pk=None):
        profile = self.get_object()
        # Example: calculate some stats for the profile
        stats_data = {
            'total_posts': profile.posts.count(),
            'follower_count': profile.followers.count()
        }
        return Response(stats_data)

This will add a new URL: GET /userprofile/<pk>/stats/

Step 3: Double-Check Your Project-Level URLs

Your existing project urls.py looks good, but since you're on Django 2.0, you can use path instead of url for cleaner syntax (though url still works):

from django.urls import path, include
urlpatterns = [
    path('userprofile/', include('UserProfile.urls', namespace='UserProfile')),
]

When using reverse lookups (like in templates or views), you can reference the auto-generated routes using the namespace and basename:

  • reverse('UserProfile:userprofile-list') → Points to the list endpoint
  • reverse('UserProfile:userprofile-detail', kwargs={'pk': 1}) → Points to the detail endpoint for profile with pk=1
  • reverse('UserProfile:userprofile-stats', kwargs={'pk': 1}) → Points to the custom stats endpoint
Quick Troubleshooting Tips
  • If you don't want the auto-generated API root view (the one that lists all endpoints), use SimpleRouter instead of DefaultRouter—it's more minimal.
  • You can still set permission_classes, authentication_classes, or pagination_class on your ViewSet just like you did with class-based views.
  • If you need to override a default action (like customizing the list response), just define a list method in your ViewSet, same as you would with a class-based view.

内容的提问来源于stack exchange,提问作者mr530

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:33:58