看看ModelViewSet其实就是空类,视图中继承了ModelViewSet,get,post,put等请求就直接继承了,不需要视图中重新写了
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
先来看看view的代码
# @Time : 2020/10/12 9:01
# @Author : LW
# @Site :
# @File : views_modelviewset.py
from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.decorators import action
from projects.models import Projects
from projects.serializer_m import ProjectModelSerializer, ProjectsNameSerializer, InterfacesNameByProjectsSerializer
class ProjectsViewSet(viewsets.ModelViewSet):
queryset = Projects.objects.all()
serializer_class = ProjectModelSerializer
ordering_fields = ['name','leader']
filterset_fields = ['id','name','leader']
# 1. 可以使用action装饰器来声明自定义的动作
# 默认情况下, 实例方法名就是动作名
# methods参数用于指定该动作支持的请求方法, 默认为get
# detail参数用于指定该动作要处理的是否为详情资源对象(url是否需要传递pk键值)
@action(methods=['get'], detail=False)
def names(self, request, *args, **kwargs):#获取项目的名字
#queryset = self.get_queryset()
# serializer = ProjectsNameSerializer(instance=queryset, many=True)
# return Response(serializer.data)
# queryset = self.filter_queryset(self.get_queryset())
#
# page = self.paginate_queryset(queryset)
# if page is not None:
# serializer = ProjectsNameSerializer(page, many=True)
# return self.get_paginated_response(serializer.data)
#
# serializer = ProjectsNameSerializer(queryset, many=True)
# return Response(serializer.data)
reponse = super().list(request, *args, **kwargs)
return reponse
@action(detail=True)
#需要传id就把detail 设置为True
def interfaces(self, request, *args, **kwargs):#获取项目1下面有哪些接口
instance = self.get_object()
serializer = InterfacesNameByProjectsSerializer(instance=instance)
return Response(serializer.data)
def get_serializer_class(self):
#根据action动作更换序列化器
return ProjectsNameSerializer if self.action == 'names' else self.serializer_class
看看url
从url中可以看到,视图中继承了ModelViewSet,请求方法不再支持get post put等方法,而是只支持action动作,所有我们要把前端的请求方法,get ,post等做一一映射,映射成ModelViewSet里面的list,create,等方法
from django.urls import path
from projects import views, views_m,views_mixins,views_modelviewset
urlpatterns = [
path('projects/', views_modelviewset.ProjectsViewSet.as_view({
'get': 'list',
'post': 'create',
}), name='proejcts-list'),
path('projects/<int:pk>/', views_modelviewset.ProjectsViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'delete': 'destroy'
})),
path('projects/names/', views_modelviewset.ProjectsViewSet.as_view({
'get': 'names',
}), name='proejcts-names'),
path('projects/<int:pk>/interfaces/', views_modelviewset.ProjectsViewSet.as_view({
'get': 'interfaces',
})),
]
序列化器serializer:
# -*- coding: utf-8 -*-
# @Time : 2020/9/22 19:36
# @Author : LW
# @Site :
# @File : serializer_m.py
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from interfaces.models import Interfaces
from projects.models import Projects
def is_unique_project_name(name):
if '项目' not in name:
raise serializers.ValidationError('项目名称中必须包含"项目"')
class ProjectModelSerializer(serializers.ModelSerializer):
#要想自定义 就重新自己写一个,把自动生成的覆盖掉
name = serializers.CharField(label='项目名称', max_length=200,
help_text='项目名称', write_only=True,
validators=[UniqueValidator(queryset=Projects.objects.all(), message='项目名已存在'),
is_unique_project_name],
error_messages="")
class Meta:
model = Projects
# all 把所有的字段拿來做自動创建序列化器
#fields = "__all__"
#自定义指定字段来创建序列化器
#python manage.py shell -i ipython
fields = ('id','name','leader','tester','programer','publish_app',"desc")
#反选
#exclude = ()
#指定不校验的字段(只进行输出,不输入校验)
#read_only_fields = ("leader")
# 7. 使用extra_kwargs参数, 可以修改未显式声明的字段的属性
# key为校验的选项名, value为自定义错误提示字符串
#也可以在这里重新制定序列化器的字段校验,和最上面重新制定name字段校验的是一样的
extra_kwargs = {
'leader': {
# 'write_only': True,
'error_messages': {'max_length': '最大长度不超过50个字节'}
},
# 可以为序列化器字段, 添加或者修改属性
'name': {
#'write_only': True,#只校验前端输入,不返回
'validators': [UniqueValidator(queryset=Projects.objects.all(), message='项目名不能重复'),
is_unique_project_name],
'label': '项目名称'
}
}
def create(self, validated_data):
# project = Projects.objects.create(**validated_data)
return Projects.objects.create(**validated_data)
def update(self, instance, validated_data):#上面序列化器fields校验啥 我们这边就创建啥
instance.name = validated_data['name']
instance.leader = validated_data['leader']
instance.tester = validated_data['tester']
instance.programer = validated_data['programer']
instance.publish_app = validated_data['publish_app']
instance.desc = validated_data['desc']
instance.save()
return instance
class Projects_Interfaces_Serializer(serializers.ModelSerializer):
# 父表中默认不会生成关联字段(从表字段), 可以手动指定, 字段名默认为 子表模型类名小写_set
interfaces_set = serializers.StringRelatedField(many=True)
class Meta:
model = Projects
fields = '__all__'
class ProjectsNameSerializer(serializers.ModelSerializer):
class Meta:
model = Projects
fields = ('id','name')
class InterfacesNameSerializer(serializers.ModelSerializer):
class Meta:
model = Interfaces
fields = ('id','name','tester')
class InterfacesNameByProjectsSerializer(serializers.ModelSerializer):
#查找项目下有多少个接口
interfaces_set = InterfacesNameSerializer(read_only=True,many=True)
class Meta:
model = Projects
fields = ('id','interfaces_set')