如何在Django Generic APIView中用单端点实现CRUD操作?
Got it, let's tackle this problem step by step. You're right that ListCreateAPIView only covers listing and creating objects, but we can combine DRF's mixins with GenericAPIView to build a custom view class that handles all four operations—no viewsets or function-based views required.
Here's the solution:
We'll create a single view class that mixes in the functionality for listing, creating, retrieving, updating, and deleting objects. Then we'll configure two URL routes (one for the collection, one for individual objects) that point to this same view, so your frontend can use a consistent base endpoint.
1. Create the Custom View Class
First, import the necessary modules and define your view by combining the required mixins with GenericAPIView:
from rest_framework import generics, mixins from .models import YourModel # Replace with your actual model from .serializers import YourModelSerializer # Replace with your actual serializer class CombinedObjectView( mixins.ListModelMixin, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView ): queryset = YourModel.objects.all() serializer_class = YourModelSerializer # Handle GET requests: return list if no pk is provided, single object if pk exists def get(self, request, *args, **kwargs): if 'pk' in kwargs: return self.retrieve(request, *args, **kwargs) return self.list(request, *args, **kwargs) # Handle POST requests (create object) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) # Handle PUT requests (full update) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) # Handle PATCH requests (partial update) def patch(self, request, *args, **kwargs): return self.partial_update(request, *args, **kwargs) # Handle DELETE requests def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
2. Configure the URLs
Add these routes to your urls.py—they'll both point to our custom view, letting the presence of a pk determine which operation runs:
from django.urls import path from .views import CombinedObjectView urlpatterns = [ # Collection endpoint: GET (list) / POST (create) path('your-objects/', CombinedObjectView.as_view(), name='object-collection'), # Detail endpoint: GET (single) / PUT / PATCH / DELETE path('your-objects/<int:pk>/', CombinedObjectView.as_view(), name='object-detail'), ]
How This Works:
- For your frontend, this feels like a single "endpoint" (
/your-objects/)—they just add apkto the URL when targeting a specific object. - The
get()method checks if apkis present in the URL parameters: if yes, it uses theRetrieveModelMixinto return a single object; if not, it usesListModelMixinto return all objects. - The other methods (
post,put,patch,delete) directly map to the corresponding mixin functionality, which handles the heavy lifting for you.
This approach stays strictly within the Generic API View ecosystem, avoids viewsets and function-based views, and aligns with REST best practices your frontend team is asking for.
内容的提问来源于stack exchange,提问作者Reactoo

