在django中迈出第一步,构建一个简单的crud api,其中我有两个实体:device和property。
我的项目urls.py
如下:
from django.contrib import admin
from django.urls import include, path
from devices.views import index
urlpatterns = [
path('', index, name='index'),
path('admin/', admin.site.urls),
path('api/', include('devices.urls')),
]
和我的应用urls.py
如下:
from django.urls import path
from . import views
urlpatterns = [
path('device/create/', views.DeviceCreate.as_view()),
path('device/update/<int:pk>/', views.DeviceUpdate.as_view()),
path('device/delete/<int:pk>/', views.DeviceDelete.as_view()),
path('device/', views.DeviceList.as_view()),
path('device/<int:pk>/', views.DeviceDetail.as_view()),
path('property/create/', views.PropertyCreate.as_view()),
path('property/update/<int:pk>/', views.PropertyUpdate.as_view()),
path('property/delete/<int:pk>/', views.PropertyDelete.as_view()),
path('property/', views.PropertyList.as_view()),
path('property/<int:pk>/', views.PropertyDetail.as_view()),
]
这有点重复,但是可以,真正的问题是我的视图文件重复得多:
from rest_framework import generics
from .models import Device, Property
from .serializers import DeviceSerializer, PropertySerializer
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
class DeviceCreate(generics.CreateAPIView):
queryset = Device.objects.all()
serializer_class = DeviceSerializer
class DeviceList(generics.ListAPIView):
queryset = Device.objects.all()
serializer_class = DeviceSerializer
class DeviceUpdate(generics.UpdateAPIView):
queryset = Device.objects.all()
serializer_class = DeviceSerializer
class DeviceDelete(generics.DestroyAPIView):
queryset = Device.objects.all()
serializer_class = DeviceSerializer
class DeviceDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Device.objects.all()
serializer_class = DeviceSerializer
class PropertyCreate(generics.CreateAPIView):
queryset = Property.objects.all()
serializer_class = PropertySerializer
class PropertyList(generics.ListAPIView):
queryset = Property.objects.all()
serializer_class = PropertySerializer
class PropertyUpdate(generics.UpdateAPIView):
queryset = Property.objects.all()
serializer_class = PropertySerializer
class PropertyDelete(generics.DestroyAPIView):
queryset = Property.objects.all()
serializer_class = PropertySerializer
class PropertyDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Property.objects.all()
serializer_class = PropertySerializer
例如,我查看了网络,这似乎是一种有效的方法(加上我的应用程序正在运行),但是有没有一种方法可以改善我的views.py
文件以更少的代码获得相同的结果?>
答案 0 :(得分:1)
在这种情况下,您应该在rest_framework中使用ModelViewSet,例如对于设备,它将是一个ViewSet,如下所示:
class DeviceViewSet(viewsets.ModelViewSet):
queryset = Device.objects.all()
serializer_class = DeviceSerializer
然后在您的urls.py
from myapp.views import DeviceViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'device', DeviceViewSet, base_name='device')
urlpatterns = router.urls
主要区别在于,对于不同的操作,您具有相同的端点。它们通过HTTP方法来区分,例如。
/devices
等于您的DeviceList
/devices/<id>
等于您的DeviceDetail
/devices
等于您的DeviceCreate
/devices/<id>
等于您的DeviceUpdate
/devices/<id>
等于您的DeviceDelete
答案 1 :(得分:1)
您可以为ModelViewSet
使用一个PropertySerializer
,为DeviceSerializer
使用一个
ModelViewSet提供默认的create
,retrieve
,update
,partial_update
,destroy
和list
操作。
您的views
看起来像这样:
class DeviceViewSet(ModelViewSet):
serializer_class = DeviceSerializer
def get_queryset(self):
return Device.objects.all()
class PropertyViewSet(ModelViewSet):
serializer_class = PropertySerializer
def get_queryset(self):
return Property.objects.all()
然后您将在urls.py
中的路由器上注册视图,如下所示:
from . import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'devices', views.DeviceViewSet, base_name='device')
router.register(r'properties', views.PropertyViewSet, base_name='property')
urlpatterns = router.urls
请注意,您的序列化器类也必须是ModelSerializer
:
class DeviceSerializer(ModelSerializer):
class Meta:
model = Device
fields = ('foo', 'bar')
class PropertySerializer(ModelSerializer):
class Meta:
model = Device
fields = ('foo', 'bar')
中了解更多信息