django rest framework简易教程

发布于 2022-04-21 01:26:39

本文为简单的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]

本文由于内容较多,写的可能不是很清晰,大家有问题可以留言,我会根据需要编写其他教程帖子。

1 条评论

发布
问题