• day83-drf


    基表的作用(继承)

    class BaseModel(models.Model):
        create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
        is_delete = models.BooleanField(verbose_name='是否删除', default=False)
        class Meta:     
            abstract = True                   # 有该属性的Model类不会完成数据库迁移产生一张表 
    
    
    class Publish(BaseModel):
        name = models.CharField(verbose_name='出版社名', max_length=32)
        address = models.CharField(verbose_name='地址', max_length=64)
        phone = models.CharField(verbose_name='电话', max_length=32)

    配置media静态文件(图片路径)

    settings.py:
    
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
    
    models.py:
    
    class Author(BaseModel):
        name = models.CharField(verbose_name='作者名', max_length=32)
        icon = models.FileField(upload_to='icon', default='icon/icon.jpg')      #传入路径和默认路径
        telephone = models.CharField(verbose_name='电话', max_length=32)
    
    其他模型类中自定义显示字段:
    @property
    def author_detail_list(self):
        author_detail_arr = []
        for author in self.authors.all():
            author_dic = {}      
            author_dic['icon'] = settings.MEDIA_URL + str(author.icon)       # author.icon是对象类型,不能序列化
            author_detail_arr.append(author_dic)
        return author_detail_arr

    模型表的外键字段处理方法

    外键处理:
    
    1.反向查询:related_name='xxx'
    
    2.表关系(db_constraint + on_delete ): 
        db_constraint=False                         数据库断开关联 ,也就是操作数据库时不进行逻辑判断,但用orm逻辑判断操作数据库
        on_delete=models.CASCADE                    级联删除,多对多表不需要写,因为默认级联删除
        on_delete=models.SET_NULL, null=True        删除时,外键字段为为空
        on_delete=models.SET_DEFAULT, default=0     删除时,外键字段为0
        on_delete=models.DO_NOTHING                 删除时,外键字段不处理  
    案例:
    class
    AuthorDetail(BaseModel): CHOICE_SEX = ( (0, ''), (1, '') ) age = models.IntegerField(verbose_name='年龄') sex = models.IntegerField(verbose_name='性别', choices=CHOICE_SEX, default=0) info = models.TextField(verbose_name='个人详情') author = models.OneToOneField(verbose_name='作者', to='Author', db_constraint=False, on_delete=models.CASCADE, related_name='detail')

     模型类

    class Book(BaseModel):
        name = models.CharField(verbose_name='书名', max_length=32)
        price = models.DecimalField(verbose_name='价格', max_digits=5, decimal_places=2, default=66.66)
        authors = models.ManyToManyField(verbose_name='作者们', to='Author', db_constraint=False, related_name='books')       
        publish = models.ForeignKey(verbose_name='出版社', to='Publish', db_constraint=False, on_delete=models.CASCADE,
                                    related_name='books')
    
        class Meta:
            db_table = 'o_Book'
            verbose_name = '书籍'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
        
        @property
        def publish_name(self):                                                       # 插拔字段(序列化使用):默认为read_only(不需要考虑反序列化),且不能修改为write_only    
            return self.publish.name
    
        @property
        def publish_detail(self):
            from . import serializers
            return serializers.PublishesModelSerializer(self.publish).data            #序列化

    序列化类

    class PublishesModelSerializer(serializers.ModelSerializer):
        class Meta:
            fields = ('name', 'address', 'phone')
            model = models.Publish
            extra_kwargs = {}
    
    
    class BooksListSerializer(serializers.ListSerializer):
        
        def create(self, validated_data):                                   # ListSerializer已提供create的实现体,有特殊需求可以重写
            return super().create(validated_data)
    
        
        def update(self, instance, validated_data):                         # ListSerializer未提供update的实现体,必须重写
            for index, book_obj in enumerate(instance):
                book_dic = validated_data[index] 
                for k, v in book_dic.items():
                    if hasattr(book_obj, k):
                        setattr(book_obj, k, v)
               
                book_obj.save()                                              # 同步到数据库
            return instance
    
    
    
    class BooksModelSerializer(serializers.ModelSerializer):
     
        class Meta:                                                            #正反序列化都会用到的字段
    
        list_serializer_class = BooksListSerializer                      # 设置群体资源(多个)校验类
        
            fields = '__all__'                                                 # 提供该表所有字段
          
            exclude = ('id', 'create_time', 'is_delete')                       # 刨除该表的某些字段 - 不常用
                    
            depth = 1                                                          # 自动深度查询(正向查询往下) - 不常用 
           
            fields = ('name', 'price', 'publish', 'authors', 'publish_name')   # 提供该表的字段和插拔式自定义字段(自定义只能在fields使用)
            
            model = models.Book
            
            
            extra_kwargs = {
             
                'authors': {
                    'write_only': True                                          # 可以区分序列化与反序列化字段
                },
                'publish_name': {
                    'read_only': True,
                },
                'price': {
                    'required': True,                                           
                    'error_messages': {                                         #提供系统默认校验信息即校验失败信息
                        'required': '价格不能为空',
                    }
                },
                'name': {
                    'min_length': 3,
                    'error_messages': {
                        'min_length': '太短',
                    }
                },
            }
        

        def validate_name(self, value: str):
          print(self.context.get('owner'))                    # 拿视图类context传递过来的参数
          if not value.isidentifier():
            raise serializers.ValidationError('名字非法')
          return value

    def create(self, validated_data):                                      #ModelSerializer重写了 update 和 create,如果没有特殊业务要求,可以不需要再重写
            authors = validated_data.pop('authors')
            book_obj = models.Book.objects.create(**validated_data)
            book_obj.authors.add(*authors)
            return book_obj

    视图类(十大接口)

    
    
    模型表继承MSerializer类时,没有写create和update方法,需要自己写
    模型表继承ModelSerializer类时,已经写了create和update方法
    模型表继承ListSerializer类时,已经写了群|单create,但update方法没有写,可以在序列化类配置,表示多数据时会走这个类的create,update

    from
    rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from . import models, serializers from utils.response import APIResponse class BooksAPIView(APIView): def get(self, request, *args, **kwargs): # 获取所有 | 一个 pk = kwargs.get('pk') if pk: books_query = models.Book.objects.filter(is_delete=False, pk=pk) else: books_query = models.Book.objects.filter(is_delete=False).order_by('id') books_data = serializers.BooksModelSerializer(books_query, many=True).data return APIResponse(0, 'ok', books_data) def post(self, request, *args, **kwargs): # 新增多个 | 一个(这里重写create) request_data = request.data many = True if isinstance(request_data, list) else False book_ser = serializers.BooksModelSerializer(data=request_data, many=many) if book_ser.is_valid(): book_obj_list = book_ser.save() return APIResponse(0, 'ok', serializers.BooksModelSerializer(book_obj_list, many=many).data) else: return APIResponse(1, 'failed', book_ser.errors) def put(self, request, *args, **kwargs): # 整体修改一个 pk = kwargs.get('pk', 1) book_obj = models.Book.objects.filter(pk=pk, is_delete=False).first() book_ser = serializers.BooksModelSerializer(instance=book_obj, data=request.data) #必须传obj if book_ser.is_valid(): #更新用系统的 book_obj = book_ser.save() return Response({ 'status': 0, 'msg': 'ok', 'results': serializers.BooksModelSerializer(book_obj).data }) else: return Response({ 'status': 1, 'msg': 'failed', 'results': book_ser.errors }) def patch(self, request, *args, **kwargs): request_data = request.data if isinstance(request_data, list): #局部群改:往 /Books/ 发送 [{"pk":1,"name":"西游记"},{"pk":2,"price":"1.00"}] pks = [book_dic.pop('pk') for book_dic in request_data] else: #局部单改:往 /Books/(pk)/ 发送 {"name":"西游记"} pks = [kwargs.get('pk')] request_data = [request_data] book_query = models.Book.objects.filter(pk__in=pks, is_delete=False) book_ser = serializers.BooksModelSerializer(partial=True, many=True, instance=book_query, data=request_data,context={‘xxx’:‘123’}) #partial=True允许局部操作反序列化字段,context=是给序列化类传递参数 if book_ser.is_valid(): book_obj_list = book_ser.save() return APIResponse(0, 'ok', serializers.BooksModelSerializer(book_obj_list, many=True).data) else: return APIResponse(1, 'failed', book_ser.errors) def delete(self, request, *args, **kwargs): # 删除一个 /books/1/ | 删除多个 /books/ 数据[1, 2] pk = kwargs.get('pk') if pk: pks = [pk] else: pks = request.data delete_rows = models.Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True) if delete_rows != 0: return APIResponse(0, 'ok') return APIResponse(1, '删除失败')

     Response类的详解

    class PublishesAPIView(APIView):
        
        def get(self, request, *args, **kwargs):
            publishes_query = models.Publish.objects.all()
            publishes_data = serializers.PublishesModelSerializer(publishes_query, many=True).data
    
            # return Response({
            #     'status': 0,
            #     'msg': 'ok',
            #     'results': publishes_data
            # })
    
            from utils.response import APIResponse
            return APIResponse(0, 'ok', result=123,
                               headers={
                'Token': 'as12df.88og5z.qw12cv'
            }, status=status.HTTP_511_NETWORK_AUTHENTICATION_REQUIRED)

      data:要返回给前台的数据
      status:响应的网络状态码
      template_name:drf也可以渲染页面
      headers:响应头
      exception:异常信息
      content_type:响应的数据类型,接口默认application/json

     Response类的二次封装

    from rest_framework.response import Response
    class APIResponse(Response):
        def __init__(self, data_status, msg, results=None, headers=None, status=None, **kwargs):
            data = {
                'status': data_status,
                'msg': msg,
            }
            if results:
                data['results'] = results
            data.update(kwargs)
            super().__init__(data=data, headers=headers, status=status)
  • 相关阅读:
    C#窗体操作的小技巧
    C#操作Xml
    Path类对路径字符串的操作
    Google Maps 基础
    C#时间操作总结
    根据地理坐标计算瓦片行列号
    使用VBA宏批量修改表格
    检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法
    Asp.net实现URL重写
    VS2013利用ajax访问不了json文件——VS2013配置webconfig识别json文件
  • 原文地址:https://www.cnblogs.com/klw1/p/11361517.html
Copyright © 2020-2023  润新知