本文为简单的django rest framework教程,前期需要部分python基础,(面向对象,类,继承等),文档仅可编写简单的CRUD。
教程中含有CRUD简单应用。此处不再讲述赘述。
目录部分:
1.模型(model)
2.序列化器(Serializer)
3.视图(View)
4.路由集(Routers)
5.自定义权限
模型(model)
dvadmin中推荐继承CoreModel,可添加系统自带字段。
CoreModel父级为models.Model,如不使用CoreModel中字段可直接继承models.Model
Model中的字段类型参考django文档:django field
from django.db import models
class Inventory(models.Model):
# 模型字段
name = models.CharField(max_length=200,verbose_name='品名')
code = models.IntegerField(verbose_name='编码')
unit = models.CharField(max_length=100,default='斤',verbose_name='单位')
class_null = models.CharField(max_length=100,verbose_name='分类')
description = models.TextField(max_length=10000,verbose_name='描述')
class Mate:
db_table = 'inventory' # 如果声明db_table将声明表名inventory。
verbose_name = '商品库存' # 在admin管理界面声明对应名称,单数形式显示
verbose_name_plural = verbose_name # 在admin管理界面声明对应名称,复数数形式显示
def __str__(self):
return f"{self.name}" # print(queryset)时对应的数据。可声明多个。
序列化器(Serializer)
系统自带序列化器CustomModelSerializer,如继承自系统自带model序列化器必须继承CustomModelSerializer。
如不需使用CustomModelSerializer,序列化器继承serializers.ModelSerializer
# 导入序列化器
from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from inventory.models import Inventory
class InventoryModelSerializers(serializers.ModelSerializer):
# 非模型内字段,在此声明(序列化嵌套,外键字段)
other = serializers.CharField(default='默认值',read_only=True)
# 声明调用的模型信息
# 必须给model声明模型,给fields声明字段列表。
class Meta:
model = Inventory
# fields = '__all__'
fields = ['name', 'code', 'unit', 'class_null', 'description', 'other']
# exclude = ['name'] # 排除此字段,与fields互斥,使用一个即可。
# read_only_fields = [] # 选填,只读字段列表,表示这些字段只会在序列化阶段使用。
# extra_kwargs = { # 选填,字段额外的选项声明,示例,可核对字段是否符合要求。
# "code":{
# "min_value": 6,
# "max_value": 20,
# "error_message": { # 如不符合报错
# "min_value": "年龄不能小于6",
# "max_value": "年龄不能大于20",
# },
# },
#
# }
# 方法重写(进阶教程中。。)
视图(View)
系统自带CustomModelViewSet,推荐继承,CRUD封装于CustomModelViewSet中。
如不需使用则继承django或rest framework中的视图类。
django下的View基类
APIView
● ViewSet
● GenericViewSet
● ModelViewSet
● ReadOnlyModelViewSet
GenericAPIView
● CreateAPIView
● ListAPIViewRetrieAPIView
● RetireveAPIView
● DestoryAPIView
● UpdateAPIView
● RetrieveUpdateAPIView
● RetieveUpdateDestoryAPIView
rest_framework提供的视图的主要作用
● 控制序列化器的执行(检验,保存,数据转换)
● 控制数据库查询的执行
● 调用请求类和响应类,并扩展其他的功能类
本文具体讲述视图基类APIView和ModelViewSet
APIView
rest_framework.views.APIView
rest_framework所有视图类的基类,继承自django的View
除了继承父类View的原有方法外,新增属性
● authentication_classes 列表或元组,身份认证类
● permissoin_classes 列表或元组,权限检查类
● throttle_classes 列表或元组,流量控制类
具体QuerySet方法请参考django文档:django QuerySet
APIView
增删改查接口实现
from rest_framework.views import APIView
from rest_framework.response import Response #rest framework中自带的Response
#框架中带有多个Response,推荐使用系统自带的Response返回数据。
from .models import Inventory
from .serializers import InventoryModelSerializers
from rest_framework import status #rest framework自带的状态返回值
class InerntoryAPIView(APIView):
# 获取数据
def get(self, request):
queryset = Inventory.objects.all() # 返回所有数据
serializer = InventoryModelSerializers(instance=queryset, many=True)
# many为True,返回多个值。
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
'''添加数据'''
serializer = InventoryModelSerializers(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
class InerntoryInfoAPIView(APIView):
# 获取单个数据
def get(self, request, pk):
try:
data = Inventory.objects.get(pk=pk) # get返回单个数据
except Inventory.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = InventoryModelSerializers(instance=data)
return Response(serializer.data)
# 修改单个数据
def put(self, request, pk):
try:
data = Inventory.objects.get(pk=pk)
except Inventory.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = InventoryModelSerializers(instance=data, data=request.data)
serializer.is_valid(raise_exception=True)
return Response(serializer.data, status=status.HTTP_201_CREATED)
#删除数据
def delete(self, request, pk):
try:
Inventory.objects.get(pk=pk).delete()
except Inventory.DoesNotExist:
pass
return Response(status=status.HTTP_204_NO_CONTENT)
ModelViewSet
最简单的CRUD使用
from rest_framework.viewsets import ModelViewSet
class InventoryModelViewSet(ModelViewSet):
queryset = Inventory.objects.all()
serializer_class = InventoryModelSerializers
ModelViewSet声明路由
from rest_framework.routers import DefaultRouter
from . import views
from django.urls import path,re_path
router = DefaultRouter() #路由注册
router.register('inventory', views.InventoryModelViewSet, basename='inventory')
urlpatterns = [
] + router.urls # 将路由添加到urlpatterns中
ModelViewSet中自定义视图方法自动生成路由
from rest_framework.decorators import action
class InventoryModelViewSet(ModelViewSet):
queryset = Inventory.objects.all()
serializer_class = InventoryModelSerializers
#action装饰器,methods:声明http方法,detail:声明URL中是否含有id,url_path自定义路径。
@action(methods=["get"], detail=True, url_path="user/loin")
def get_no_inventory(self, request, *args, **kwargs):
...
自定义权限
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
自定义权限只允许对象的所有者编辑它。
"""
def has_object_permission(self, request, view, obj):
# 读取权限允许任何请求,
# 所以我们总是允许GET,HEAD或OPTIONS请求。
if request.method in permissions.SAFE_METHODS:
return True
# 只有该数据的所有者才允许写权限。
return obj.permission == request.user
# 返回bool类型,也就是函数内可写你需要判断的用户属性,return False为不允许,True为允许。
在Views中导入权限信息
from apps.project.permissions import IsOwnerOrReadOnly
class ProjectModelViewSet(CustomModelViewSet):
"""
项目管理 的CRUD视图
"""
queryset = Project.objects.all()
serializer_class = ProjectSerializer
permission_classes = [IsOwnerOrReadOnly]
本文由于内容较多,写的可能不是很清晰,大家有问题可以留言,我会根据需要编写其他教程帖子。
等巨佬的进阶教程和权限管理教材