记录下这些view的使用,方便以后查阅
from django.db import models
f import settings
dels import BaseModelclass Projects(BaseModel):id = models.AutoField(primary_key=True,verbose_name='id主键',help_text='id主键')name = models.CharField('项目名称', max_length=40, unique=True, help_text='项目名称')leader = models.ForeignKey(to = settings.AUTH_USER_MODEL, verbose_name='负责人',null=True, on_delete=models.SET_NULL, related_name='projects_leader')desc = models.CharField('项目描述', max_length=200, null=True, blank=True, default='',help_text='项目描述')class Meta:db_table = 'tb_projects'verbose_name = '项目信息'verbose_name_plural = verbose_nameordering = ['-c_time']def __str__(self):return self.name
from rest_framework import serializers
dels import Projectsclass ProjectModelSerializer(serializers.ModelSerializer):email = serializers.EmailField(write_only=True)leader = serializers.ReadOnlyField(source='leader.username')def validate_name(self, value):value: strif dswith('项目'):raise serializers.ValidationError('项目名称必须得以“项目”结尾')return valuedef create(self, validated_data: dict):validated_data.pop('email')obj = ate(**validated_data)return objdef update(self, instance, validated_data):instance.name = ('name') instance.save()return instance class Meta:model = Projectsexclude = ['is_delete', 'u_time']
from rest_framework import status
from sponse import Response
from rest_framework.views import APIView
dels import Projects
from projects.serializers import ProjectModelSerializerclass ProjectsViews(APIView):# 获取数据库所有数据def get(self,request):# 从数据库查询出所有的数据project_list = Projects.objects.all()# 使用serializers里定义的序列化器对库里查出来的数据进行序列化,instance: 要序列化的对象,就是从库里查出来的数据# many: 如果是查询集对象,many=True;如果是单个对象,many=Falseserializer = ProjectModelSerializer(instance=project_list,many=True)# 将序列化后的数据返回给前端,serializer.data序列化后是字典return Response(serializer.data)# 新增def post(self,request):# 获取前端传过来的数据,字典格式传入data进行反序列化,创建序列化器对象serializer = ProjectModelSerializer(data=request.data)# 校验数据if serializer.is_valid(): # 如果是TRUE,表示数据校验通过,通过,就保存# 如果instance为None,调用save本质会调用create--》父类create直接抛异常,所以我们要重写# 序列化器对象调用save方法时,会调用序列化器类中的create方法,进行数据创建操作serializer.save() # 就会保存,重写create方法,如果不重写,我们不知道存到哪个表中,前提是使用的serializer,不是modelserializer# return Response(serializer.data)return Response(serializer.data, status=status.HTTP_200_OK)return Response({'code':101,'msg':'数据校验失败','err':s})class ProjectsDetailViews(APIView):# 获取数据库单条数据def get(self,requet,pk):project_detail_list = Projects.objects.filter(pk=pk).first()serializer = ProjectModelSerializer(instance=project_detail_list)if project_detail_list:return Response(serializer.data)else:return Response({'code':103,'msg':'数据不存在'}, status=status.HTTP_204_NO_CONTENT)# 修改单条数据def put(self,request,pk):# 用什么数据,修改哪条数据project_update_one = Projects.objects.filter(pk=pk).first()# 进行序列化,既有instance又有data,表示修改serializer = ProjectModelSerializer(instance=project_update_one,data=request.data)# 校验数据if serializer.is_valid():serializer.save() # 重写update方法return Response(serializer.data)return Response({'code':102,'msg':'修改出错','err':s})# 删除def delete(self,request,pk):# 先获取要删除哪条数据project_del_one = Projects.objects.filter(pk=pk).delete()if project_del_one[0]>0:return Response({'code':100,'msg':'删除成功'}, status=status.HTTP_204_NO_CONTENT)else:return Response({'code':103,'msg':'数据不存在'}, status=status.HTTP_204_NO_CONTENT)
INSTALL_APPS = {
...
'django_filters',
...
}
REST_FRAMEWORK = {
# 通用配置,所有的视图默认使用 #全局配置,对全部视图的查询多条接口都有过滤功能,但是视图里要指定字段
'DEFAULT_FILTER_BACKENDS': ['st_framework.DjangoFilterBackend']
}
class EmployeeViewSet(ModelViewSet):queryset = Employee.objects.all()serializer_class = EmployeeSerializer# 指定可以根据哪些字段进行列表数据的过滤filterset_fields = ('gender', 'department')
# 单独视图配置
from st_framework import DjangoFilterBackend
class APIView):...# 指定过滤器fitler_backends = [DjangoFilterBackend]# 指定可以根据哪些字段进行列表数据的过滤filterset_fields = ['project', 'project__name']
class EmployeeViewSet(ModelViewSet):queryset = Employee.objects.all()serializer_class = EmployeeSerializer# 新增排序的过滤器filter_backends = [..., OrderingFilter]# 指定可以根据哪此字段进行排序ordering_fields = ('age', 'salary')
REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 2 # 每页显示多少条数据
}
定义完分页器后,可以在某个视图里面进行使用:
class DepartmentViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):...# 指定分页配置pagination_class =
如果url是127.0.0.1/department?page=3&page_size=5,代表打开第3页,每一页显示5条数据。
class MyPageNumberPagination(PageNumberPagination): # 指定默认每一页显示的数据条数page_size = 3# 前端用于指定页号的查询字符串参数名称page_query_param = 'page'# 指定前端用于指定页号的查询字符串参数的描述page_query_description = '获取的页码'# page_size_query_param = "page_size"# 前端用于指定每一页的数据条数,查询字符串参数名称# 只要设置了page_size_query_param,那么前端就支持指定获取每一页的数据条数page_size_query_param = "size"# 前端用于指定每一页的数据条数,查询字符串参数的描述page_size_query_description = '每一页数据条数'max_page_size = 100def get_paginated_response(self, data):response = super().get_paginated_response(data)response.data['current_page_num'] = self.page.numberresponse.data['total_pages'] = self.page.paginator.num_pagesreturn response
from rest_framework import status
from ics import GenericAPIView
from sponse import Response
dels import Projects
from projects.serializers import ProjectModelSerializerclass ProjectsViews(GenericAPIView):# 需要指定queryset和serializer_classqueryset = Projects.objects.all()serializer_class = ProjectModelSerializer# 指定可以根据哪些字段进行列表数据的过滤 ?name=filterset_fields = ('name', 'leader')# 需要新增排序的过滤器filter_backends = [DjangoFilterBackend,OrderingFilter]# 指定可以根据哪此字段进行排序ordering_fields = ('id')# 分页pagination_class = PageNumberPaginationdef get(self, request):# 直接从数据库取出来数据进行了序列化serializer = _serializer(instance_queryset(), many=True)return Response(serializer.data, status=status.HTTP_200_OK)def post(self,request):serializer = _serializer(data = request.data)serializer.is_valid(raise_exception = True)serializer.save()return Response(serializer.data,status = status.HTTP_201_CREATED)class ProjectsDetailViews(GenericAPIView):queryset = Projects.objects.all()serializer_class = ProjectModelSerializerdef get(self,request):serializer = _serializer(instance = _object())return Response(serializer.data,status=status.HTTP_200_OK)def put(self,request):serializer = _serializer(instance = _object(),data = request.data)serializer.is_valid(raise_exception=True)serializer.save()return Response(serializer.data, status=status.HTTP_201_CREATED)def delete(self,request):_object().delete()return Response({'code':1003,'msg':'数据删除成功'},status=status.HTTP_204_NO_CONTENT)
具备的类属性和方法
类属性:
queryset = None
serializer_class = None
lookup_field = ‘pk’
lookup_url_kwarg = None
filter_backends =api_settings.DEFAULT_FILTER_BACKENDS
pagination_class =api_settings.DEFAULT_PAGINATION_CLASS
queryset是用来控制视图返回给前端的数据。如果没什么逻辑,可以直接写在视图的类属性中,如果逻辑比较复杂,也可以重写get_queryset方法用来返回一个queryset对象。如果重写了get_queryset,那么以后获取queryset的时候就需要通过调用get_queryset方法。因为queryset这个属性只会调用一次,以后所有的请求都是使用他的缓存。
当前类视图的内部的实例方法会用到的序列化器类
在检索的时候,根据什么参数进行检索。默认是pk,也就是主键。
在检索的url中的参数名称。默认没有设置,跟lookup_field保持一致。
用于过滤查询集的过滤器后端类的列表。默认值与DEFAULT_FILTER_BACKENDS 设置的值相同。
当分页列出结果时应使用的分页类。默认值与DEFAULT_PAGINATION_CLASS 设置的值相同,即 ‘rest_framework.pagination.PageNumberPagination’。
方法:
默认返回由 queryset 属性指定的查询集。默认是返回数据库全部数据,如果想返回其他数据,需要自定义。
def get_queryset(self):assert self.queryset is not None, ("'%s' should either include a `queryset` attribute, ""or override the `get_queryset()` method."% self.__class__.__name__)queryset = self.queryset # 设置queryset等于一个查询集,这里的queryset等于self的querysetif isinstance(queryset, QuerySet): # 判断queryset是不是查询集类型queryset = queryset.all() # 是的话就获取所有数据,然后返回return queryset
返回详情pk视图所需的模型类数据对象。默认使用 lookup_field 参数过滤基本的查询集。
def get_object(self):queryset = self.filter__queryset())# Perform the lookup filtering.lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_fieldassert lookup_url_kwarg in self.kwargs, ('Expected view %s to be called with a URL keyword argument ''named "%s". Fix your URL conf, or set the `.lookup_field` ''attribute on the view correctly.' %(self.__class__.__name__, lookup_url_kwarg))filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}obj = get_object_or_404(queryset, **filter_kwargs)# May raise a permission deniedself.check_object_quest, obj)return obj返回具体pk值的数据def get_object(self,pk):try:return (id=pk)except Exception:raise Http404
返回一个序列化器的实例,不需要重写get_serializer()方法,直接调用即可
def get_serializer(self, *args, **kwargs):serializer_class = _serializer_class() # 调用上面的方法获取serializer_class属性再返回kwargs.setdefault('context', _serializer_context())return serializer_class(*args, **kwargs)
返回应用于序列化的类。默认为返回 serializer_class 属性的值。如果您需要根据传入请求提供不同的序列化,您可能需要重写它。
def get_serializer_class(self):assert self.serializer_class is not None, ("'%s' should either include a `serializer_class` attribute, ""or override the `get_serializer_class()` method."% self.__class__.__name__)return self.serializer_class # 返回一个serializer_class,模型序列化器
默认不需要过滤,如果需要过滤需要重写
filter_queryset()方法
def filter_queryset(self, queryset):"""Given a queryset, filter it with whichever filter backend is in use.You are unlikely to want to override this method, although you may needto call it either from a list view, or from a custom `get_object`method if you want to apply the configured filtering backend to thedefault queryset."""for backend in list(self.filter_backends):queryset = backend().filter_quest, queryset, self)return queryset
a、默认不需要分页,如果需要分页需要重写paginate_queryset()方法
b、如果self.paginator 为 None,不需要进行过滤,否则需要通过self.paginator.paginate_queryset()方法进行过滤
def paginate_queryset(self, queryset):"""Return a single page of results, or `None` if pagination is disabled."""if self.paginator is None:return Nonereturn self.paginator.paginate_queryset(queryset, quest, view=self)
扩展类 | 作用 | 封装的方法 | 状态码(成功、失败) |
---|---|---|---|
ListModelMixin | 查询多条数据 | list | 200 |
CreateModelMixin | 新增一条数据 | create | 201/400 |
RetrieveModelMixin | 查询一条数据 | retrieve | 200/404 |
UpdateModelMixin | 更新一条数据 | update/partial_update | 200/400 |
DestroyModelMixin | 删除一条数据 | destroy | 204/404 |
from rest_framework.filters import OrderingFilter
from ics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
dels import Projects
from projects.serializers import ProjectModelSerializerclass ProjectsViews(ListModelMixin, CreateModelMixin, GenericAPIView):# 需要指定queryset和serializer_classqueryset = Projects.objects.all()serializer_class = ProjectModelSerializerdef get(self, request):return self.list(request)def post(self, request):ate(request)class ProjectsDetailViews(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):queryset = Projects.objects.all()serializer_class = ProjectModelSerializerdef get(self, request, pk):ieve(request, pk)def post(self, request, pk):return self.update(request, pk)def delete(self, request, pk):return self.destroy(request, pk)
视图 | 作用 | 方法 |
---|---|---|
ListAPIView | 查询多条数据 | get |
CreateAPIView | 新增一条数据 | post |
RetrieveAPIView | 查询一条数据 | get |
UpdateAPIView | 更新一条数据 | put/patch |
DestroyAPIView | 删除一条数据 | delete |
RetrieveUpdateAPIView | 查询,更新一条数据 | get/put/patch |
RetrieveUpdateDestroyAPIView | 获取,更新,删除一条数据 | get/put/patch/delete |
class DepartmentListAPIView(ListAPIView,CreateAPIView):”“”实现了查询多条数据和新增一条数据的功能"""queryset = Department.objects.all()serializer_class = DepartmentSerializerclass DepartmentDetailAPIView(RetrieveUpdateDestroyAPIView):"""实现了查询一条数据、修改一条数据、删除一条数据的功能"""queryset = Department.objects.all()serializer_class = DepartmentSerializer
class ProjectsViews(ModelViewSet):# 需要指定queryset和serializer_classqueryset = Projects.objects.all()serializer_class = ProjectModelSerializer
路由
urlpatterns = [path('projects', views.ProjectsViews.as_view({'get':'list','post':'create'})),path('projects/<int:pk>', views.ProjectsDetailViews.as_view({'get':'retrieve','put':'update','delete':'destroy'}))
]
本文发布于:2024-01-29 11:52:11,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170650033715080.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |