- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
你问我使用DRF视图组件快速写接口?九九归一剑诀早就准备好了,没有副作用!
DRF框架提供了很多通用的视图基类与扩展类,上篇使用的APIView是比较偏Base的,视图的使用更加简化了代码,这里介绍一下其他视图的用法
Django REST framwork 提供的视图的主要作用:
先来看看这其中的人情世故:两个视图基本类,五个扩展类,九个视图子类,视图集方法,视图集··
导入:
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
扩展类不是视图类,没有集成APIView,需要配合GenericAPIView使用,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法
主要是用来对数据进行增删改查
导入
from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
导入
from rest_framework.generics import CreateAPIView,ListAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView
视图子类其实可以理解为GenericAPIView通用视图类和Mixin扩展类的排列组合组成的,底层事通过封装和继承来写
提供 post 方法
继承自: GenericAPIView、CreateModelMixin
提供 get 方法
继承自:GenericAPIView、ListModelMixin
提供 delete 方法
继承自:GenericAPIView、DestoryModelMixin
提供 get 方法
继承自: GenericAPIView、RetrieveModelMixin
提供 put 和 patch 方法
继承自:GenericAPIView、UpdateModelMixin
提供get 和 post方法
继承自:ListModelMixin、CreateModelMixin、GenericAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
提供:get、delete方法
继承自:RetrieveModelMixin、DestroyModelMixin、GenericAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin
导入
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin
ModelViewSet:继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
ReadOnlyModelViewSet:继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。
ViewSet:继承自APIView与ViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典({'get'
:'list'
})的映射处理工作。
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
GenericViewSet:使用ViewSet通常并不方便,因为list
、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView。
GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如
{'get'
:'list'
}`)的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。
第一层是继承APIView写,第二层基于基于GenericAPIView写,第三层基于GenericAPIView+五个扩展类写,第四层通过九个视图子类来写,第五层是通过ViewSet写
ps:第几层是我意淫出来的词不要介意~,一层更比一层牛,欲练此功必先自宫!!!
class BookView(APIView):
def get(self, requets):
# 序列化
book_list = models.Book.objects.all()
# 序列化多条数据many=True
ser = serializer.BookSerializer(instance=book_list, many=True)
return Response(ser.data)
def post(self, request):
# 获取反序列化数据
ser = serializer.BookSerializer(data=request.data)
if ser.is_valid():
# 校验通过存入数据库,不需要重写create方法了
ser.save()
return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
# 校验失败
return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})
class BookViewDetail(APIView):
def get(self, request, pk):
book = models.Book.objects.filter(pk=pk).first()
ser = serializer.BookSerializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = models.Book.objects.filter(pk=pk).first()
# 修改,instance和data都要传
ser = serializer.BookSerializer(instance=book, data=request.data)
if ser.is_valid():
# 校验通过修改,不需要重写update
ser.save()
return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
# 校验不通过
return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors})
def delete(self, request, pk):
models.Book.objects.filter(pk=pk).delete()
return Response({'code': 100, 'msg': '删除成功'})
ModelSerializer序列化器实战 - HammerZe - 博客园 (cnblogs.com)
-GenericAPIView 继承了APIView,封装了一些属性和方法,跟数据库打交道
-queryset = None # 指定序列化集
-serializer_class = None # 指定序列化类
-lookup_field = 'pk' # 查询单条,分组分出来的参数,转换器对象参数的名字
-filter_backends # 过滤排序功能会用它
-pagination_class # 分页功能
-get_queryset() # 获取要序列化的数据,后期可能会重写
-get_object() # 通过lookup_field查询的
-get_serializer() # 使用它序列化
-get_serializer_class() # 返回序列化类 ,后期可能重写
demo:
# 指定序列化集
queryset = models.Book.objects.all()
# 指定序列化类
serializer_class = serializer.BookSerializer
from rest_framework.response import Response
from app01 import models
from app01 import serializer
from rest_framework.generics import GenericAPIView
# 书视图类
class BookView(GenericAPIView):
# 指定序列化集
queryset = models.Book.objects.all()
# 指定序列化类
serializer_class = serializer.BookSerializer
def get(self, requets):
# obj = self.queryset()
obj = self.get_queryset() # 等同于上面
# ser = self.get_serializer_class()(instance=obj,many=True)
ser = self.get_serializer(instance=obj,many=True) # 等同于上面
return Response(ser.data)
def post(self, request):
# 获取反序列化数据
# ser = serializer.BookSerializer(data=request.data)
ser = self.get_serializer(data = request.data)
if ser.is_valid():
# 校验通过存入数据库,不需要重写create方法了
ser.save()
return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
# 校验失败
return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})
class BookViewDetail(GenericAPIView):
# 指定序列化集
queryset = models.Book.objects.all()
# 指定序列化类
serializer_class = serializer.BookSerializer
def get(self, request, pk):
# book = models.Book.objects.filter(pk=pk).first()
book = self.get_object() # 根据pk拿到单个对象
# ser = serializer.BookSerializer(instance=book)
ser = self.get_serializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
# book = models.Book.objects.filter(pk=pk).first()
book = self.get_object()
# 修改,instance和data都要传
# ser = serializer.BookSerializer(instance=book, data=request.data)
ser = self.get_serializer(instance=book,data=request.data)
if ser.is_valid():
# 校验通过修改,不需要重写update
ser.save()
return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
# 校验不通过
return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors})
def delete(self, request, pk):
# models.Book.objects.filter(pk=pk).delete()
self.get_object().delete()
return Response({'code': 100, 'msg': '删除成功'})
路由
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookViewDetail.as_view())
总结:到第二层只需修改queryset
和serializer_class
类属性即可,其余都不需要修改
注意:虽然pk没有在orm语句中过滤使用,但是路由分组要用,所以不能删,或者写成*args **kwargs
接收多余的参数,且路由转换器必须写成pk
# 源码
lookup_field = 'pk'
lookup_url_kwarg = None
get_queryset()
方法可以重写,如果我们需要在一个视图类内操作另外表模型,来指定序列化的数据
class BookViewDetail(GenericAPIView):
queryset = models.Book.objects.all()
···
'''
指定序列化数据的格式:
self.queryset()
self.get_queryset() # 等同于上面
queryset = models.Book.objects.all()
'''
# 可以重写get_queryset方法在book视图类里操作作者模型
def get_queryset(self,request):
if self.request.path == '/user'
return Author.objects.all()
···
# 这样序列化的数据就不一样了,根据不同的条件序列化不同的数据
'''当然还可以通过重写get_serializer_class来返回其他序列化器类'''
五个视图扩展类:from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
通过GenericAPIView+视图扩展类来使得代码更简单,一个接口对应一个扩展类,注意扩展类不是视图类
注意:CreateModelMixin扩展类提供了更高级的方法,可以通过重写来校验数据存入
def perform_create(self, serializer):
serializer.save()
from app01 import models
from app01 import serializer
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
# 获取所有和新增API
class BookView(ListModelMixin,CreateModelMixin,GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request):
return super().list(request)
def post(self, request):
return super().create(request)
# 获取删除修改单个API
class BookViewDetail(UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin,GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request, *args,**kwargs):
return super().retrieve(request, *args,**kwargs)
def put(self, request, *args,**kwargs):
return super().update(request, *args,**kwargs)
def delete(self, request, *args,**kwargs):
return super().destroy(request, *args,**kwargs)
总结
通过进一次封装+继承代码也变得越来越少了
模型
from django.db import models
# Create your models here.
# build four model tables
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=2, max_digits=5)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
# 自定制字段
@property
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.city}
@property
def author_list(self):
l = []
print(self.authors.all()) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
for author in self.authors.all():
print(author.author_detail) # AuthorDetail object (1)
l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr})
return l
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
def __str__(self):
return self.name
@property
def authordetail_info(self):
return {'phone':self.author_detail.telephone,'addr':self.author_detail.addr}
class AuthorDetail(models.Model):
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
序列化器
from django.db import models
# Create your models here.
# build four model tables
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=2, max_digits=5)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
# 自定制字段
@property
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.city}
@property
def author_list(self):
l = []
print(self.authors.all()) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
for author in self.authors.all():
print(author.author_detail) # AuthorDetail object (1)
l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr})
return l
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
def __str__(self):
return self.name
@property
def authordetail_info(self):
return {'phone':self.author_detail.telephone,'addr':self.author_detail.addr}
class AuthorDetail(models.Model):
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
视图
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
UpdateModelMixin
from app01 import models
from app01 import serializer
# 书视图类
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request):
return super().list(request)
def post(self, request):
return super().create(request)
class BookViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
# 作者
class AuthorView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = models.Author.objects.all()
serializer_class = serializer.AuthorSerializer
def get(self, request):
return super().list(request)
def post(self, request):
return super().create(request)
class AuthorViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = models.Author.objects.all()
serializer_class = serializer.AuthorSerializer
def get(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
# 作者详情
class AuthorDetailView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = models.AuthorDetail.objects.all()
serializer_class = serializer.AuthorDetailSerializer
def get(self, request):
return super().list(request)
def post(self, request):
return super().create(request)
class OneAuthorViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = models.AuthorDetail.objects.all()
serializer_class = serializer.AuthorDetailSerializer
def get(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
# 出版社
class PublishView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = models.Publish.objects.all()
serializer_class = serializer.PublishSerializer
def get(self, request):
return super().list(request)
def post(self, request):
return super().create(request)
class PublishViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = models.Publish.objects.all()
serializer_class = serializer.PublishSerializer
def get(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return super().destroy(request, *args, **kwargs)
路由
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 书
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookViewDetail.as_view()),
# 作者
path('authors/', views.AuthorView.as_view()),
path('authors/<int:pk>', views.AuthorViewDetail.as_view()),
# 作者详情
path('authorsdetail/', views.AuthorDetailView.as_view()),
path('authorsdetail/<int:pk>', views.OneAuthorViewDetail.as_view()),
# 出版社
path('publish/', views.PublishView.as_view()),
path('publish/<int:pk>', views.PublishViewDetail.as_view()),
]
Postman以及测完,请放心使用~
导入视图子类:from rest_framework.generics import CreateAPIView,ListAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView
使用哪个继承哪个就可以了,具体可以看继承的父类里有什么方法不需要刻意去记
from rest_framework.generics import CreateAPIView,ListAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView
# 1、查询所有,新增API
class BookView(ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 2、新增接口
class BookView(CreateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 3、查询接口
class BookView(ListAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 4、查询单个,修改一个,删除一个接口
class BookViewDetail(RetrieveUpdateDestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 5、查询单个接口
class BookViewDetail(RetrieveAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 6、修改单个接口
class BookViewDetail(UpdateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 7、删除单个接口
class BookViewDetail(DestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 8、查询单个、修改接口
class BookViewDetail(RetrieveUpdateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
# 9、查询单个、删除接口
class BookViewDetail(RetrieveDestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
'''上述共九个视图子类,九九归一剑诀~'''
# 更新和删除接口自己整合
class BookViewDetail(UpdateAPIView,DestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from app01 import models
from app01 import serializer
class BookView(ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
class BookViewDetail(RetrieveUpdateDestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
'''其余的和第三层一样'''
视图集导入:from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin
路由导入:from rest_framework.routers import SimpleRouter,DefaultRouter
基于ViewSet视图集写,需要我们配置路由
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from app01 import views
router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
...
]
urlpatterns += router.urls
'''
register(self, prefix, viewset, basename=None)
prefix:路由url前缀
viewset:处理请求的viewset类
basename:路由名称的前缀,一般和prefix写成一样就行
'''
# 等同于
path('books/'),include(router.urls)
path('books/<int:pk>'),include(router.urls)
router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
...
url(r'^', include(router.urls))
]
# 生成两种路由
path('/api/v1'),include(router.urls)
# [<URLPattern '^books/$' [name='books-list']>, <URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>]
# 等同于自己配的
path('/api/v1/books/'),include(router.urls)
path('/api/v1/books/<int:pk>'),include(router.urls)
异同:
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookViewDetail.as_view()),
两种不同的路由
views.py
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin
class BookView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from app01 import views
router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/',include(router.urls)),
]
ps:剩下的都一样~
继承该ReadOnlyModelViewSet视图集的作用是只读,只做查询,修改删除等操作不允许
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin
class BookView(ReadOnlyModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
本质
PS:ViewSetMixin控制了路由写法
ViewSet = ViewSetMixin+APIView
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
GenericViewSet = ViewSetMixin+GenericAPIView
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
魔术视图类,控制自动生成路由,可以通过组合继承,以前的写法可以继续使用,但是如果要自动生成路由必须得继承ViewSetMixin及其子类;或者选择继承ViewSet、GenericViewSet
class ViewSetMixin:
"""
This is the magic.
Overrides `.as_view()` so that it takes an `actions` keyword that performs
the binding of HTTP methods to actions on the Resource.
For example, to create a concrete view binding the 'GET' and 'POST' methods
to the 'list' and 'create' actions...
view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
"""
这就是魔法。
重写' .as_view() ',以便它接受一个' actions '关键字执行
将HTTP方法绑定到资源上的动作。
例如,创建绑定'GET'和'POST'方法的具体视图
到“列表”和“创建”动作…
= MyViewSet视图。 As_view ({'get': 'list', 'post': 'create'})
class BookView(APIView):
def get(self, requets):
book_list = models.Book.objects.all()
ser = serializer.BookSerializer(instance=book_list, many=True)
return Response(ser.data)
queryset
和serializer_class
指定序列化集和序列化器即可,一个视图类内写一次即可,最后通过get_queryset
和get_serializer
方法处理class BookView(GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, requets):
obj = self.get_queryset()
ser = self.get_serializer(instance=obj,many=True)
return Response(ser.data)
class BookView(ListModelMixin,CreateModelMixin,GenericAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request):
return super().list(request)
class BookView(ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
class BookView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
'''路由'''
router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/',include(router.urls)),
]
在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。
举例:
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
class StudentModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
def login(self,request):
"""学生登录功能"""
return Response({"message":"登录成功"})
url的定义
urlpatterns = [
path("students8/", views.StudentModelViewSet.as_view({"get": "list", "post": "create"})),
re_path("students8/(?P<pk>\d+)/",
views.StudentModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
path("stu/login/",views.StudentModelViewSet.as_view({"get":"login"}))
]
在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。
例如:
from rest_framework.viewsets import ModelViewSet
from students.models import Student
from .serializers import StudentModelSerializer
from rest_framework.response import Response
class StudentModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
def get_new_5(self,request):
"""获取最近添加的5个学生信息"""
# 操作数据库
print(self.action) # 获取本次请求的视图方法名
通过路由访问到当前方法中.可以看到本次的action就是请求的方法名
累死🐵,有错误请指正~感谢
我错过了什么,我已完成 的安装指南中要求的所有步骤 native 脚本 运行 tns doctor 给我以下输出... C:\abc\xyz>tns doctor √ Getting environm
尝试从 {addToCart(book)}}/>}> 传递数据至}> 问题: 购物车 ( render={()=> ) 收到 null,但没有收到我尝试发送的对象 已放置“console.log...
这是 _app.tsx 的外观: function MyApp({ Component, pageProps }: AppProps) { return } 我在构建项目时遇到了这个错误: Ty
我的 Laravel Vue 组件收到以下警告: [Vue warn]: Avoid mutating a prop directly since the value will be overwrit
根据这个example更详细this one我刚刚遇到了一件奇怪的事情...... 如果我使用方法作为 addTab(title,icon,component) 并且下一步想使用 setTabComp
目前我有一个捕获登录数据的表单,一个带有 TIWDBGrid 的表单,它应该返回与我从我的 mysql 数据库登录时创建的 user_id 关联的任何主机,以及一个共享数据模块。 下面是我的登录页面代
在我的react-native应用程序中,我目前有一个本地Android View (用java编写)正确渲染。当我尝试将我的react-native javascript 组件之一放入其中时,出现以
我为作业编写了简单的代码。我引用了文档和几个 youtube 视频教程系列。我的 react 代码是正确的我在运行代码时没有收到任何错误。但是这些 react-boostrap 元素没有渲染。此代码仅
几周前我刚刚开始使用 Flow,从一周前开始我就遇到了 Flow 错误,我不知道如何修复。 代码如下: // @flow import React, { Component } from "react
我想在同一个 View 中加载不同的 web2py 组件,但不是同时加载。我有 5 个 .load 文件,它们具有用于不同场景的表单字段,这些文件由 onchange 选择脚本动态调用。 web2py
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 6年前关闭。 Improve t
Blazor 有 InputNumber将输入限制为数字的组件。然而,这呈现了一个 firefox 不尊重(它允许任何文本)。 所以我尝试创建一个过滤输入的自定义组件: @inherits Inpu
我在学习 AngularDART 组件时编写了以下简单代码,但没有显示任何内容,任何人都可以帮助我知道我犯了什么错误: 我的 html 主文件:
我想在初始安装组件时或之后为 div 设置动画(淡入)。动画完成后,div 不应消失。我正在尝试使用 CSSTransition 组件并查看 reactcommunity.org 上的示例,但我根本无
我需要一个 JSF 组件来表示甘特图。是否有任何组件库(如 RichFaces)包含这样的组件? 最佳答案 JFreeChart有甘特图和PrimeFaces有一个图像组件,允许您动态地流式传输内容。
从软件工程的角度来看,组件、模块和子系统之间有什么区别? 提前致谢! 最佳答案 以下是 UML 2.5 的一些发现: 组件:该子句指定一组结构,可用于定义任意大小和复杂性的软件系统。特别是,它将组件指
我有使用非托管程序集(名为 unmanaged.dll)的托管应用程序(名为 managed.exe)。到目前为止,我们已经创建了 Interop.unmanaged.dll,managed.exe
我有一个跨多个应用程序复制的 DAL(我知道它的设计很糟糕,但现在忽略它),我想做的是这个...... 创建一个将通过所有桌面应用程序访问的 WCF DAL 组件。任何人都可以分享他们对关注的想法吗?
我有一个 ComboBox 的集合声明如下。 val cmbAll = for (i /** action here **/ } 所有这些都放在一个 TabbedPane 中。我想这不是问题。那么我
使用 VB6 创建一个 VB 应用程序。应用程序的一部分显示内部的闪存。 当我使用 printform它只是打印整个应用程序。我不知道如何单独打印闪光部分。任何帮助,将不胜感激!.. 谢谢。 最佳答案
我是一名优秀的程序员,十分优秀!