zoukankan      html  css  js  c++  java
  • drf表操作

    drf表操作

    一、面向对象二次封装Response

    ​ 为方便多次调用Response方法,可将Response进行二次封装

    ​ response.py:

    from rest_framework.response import Response
    
    
    class APIResponse(Response):
        # 格式化data
        def __init__(self, status=0, msg='ok', results=None, http_status=None, headers=None, exception=False, **kwargs):
            data = {  # json的response基础有数据状态码和数据状态信息
                'status': status,
                'msg': msg
            }
            if results is not None:  # 后台有数据,响应数据
                data['results'] = results
            data.update(**kwargs)  # 后台的一切自定义响应数据直接放到响应数据data中
            super().__init__(data=data, status=http_status, headers=headers, exception=exception)
    

    ​ views.py:

    class BookAPIView(APIview):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                book_obj = models.Book.bojects.filter(pk=pk).first()
                if not boot_obj:
                    # 以下内容被封装
    				# return Response({
                    #     'status': 1,
                    #     'msg': 'pk error'
                    # }, status=400)
                    return APIResponse(1, 'pk error', http_static=400)
                book_data = serializers.BookModelSerializer(book_obj).data
                            # return Response({
                #     'status': 0,
                #     'msg': 'ok',
                #     'results': car_data
                # })
                return APIResponse(results=book_data)
    

    二、模型基表

    ​ Model类的内部配置Meta类要设置abstract=True,这样的Model类就是用来作为基表。

    ​ models.py:

    class BookModel(models.Model):
        is_delete = models.BooleanField(default=False)
        create_time = models.DateField(auto_now_add=Ture)
        
        class Meta:
            # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
            abstract = Ture
    

    三、多表ORM关联操作

    3.1 表断关联

    ​ 1、表之间没有外键关联,但是有外键逻辑关联(有充当外键的字段)

    ​ 2、断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率(不影响增删改查操作)

    ​ 3、断关联一定要通过逻辑保证表之间数据的安全

    ​ 4、断关联

    ​ 5、级联关系:

    ​ 作者没了,详情也没:on_delete=models.CASCADE

    ​ 出版社没了,书还是那个出版社出版:on_delete=models.DO_NOTHING

    ​ 部门没了,员工没有部门(空不能):null=True, on_delete=models.SET_NULL

    ​ 部门没了,员工进入默认部门(默认值):default=0, on_delete=models.SET_DEFAULT

    ​ models.py:

    class Book(BaseModel):
        name = models.CharField(max_length=16)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING)
        # 多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联
        # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表
        author = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)
        
        # 自定义连表深度,不需要反序列化,因为自定义插拔属性不参与反序列化
        @property
        def publish_name(self):
            return self.publish.name
        
        @property
        def author_list(self):
            temp_author_list = []
            for author in self.authors.all():
                temp_author_list.append({
                    'name': author.name,
                    'sex': author.get_sex_display(),
                    'mobile': author.detail.mobile
                })
            return temp_author_list
        
    class Publish(baseModel):
        name = models.CharField(max_length=16)
        sex = models.IntegerField(choices=[(0,'男'),(1,'女')], default=0)
        
    class AuthorDetail(BaseModel):
        mobile = models.CharField(max_length=11)
        # 有作者可以没有详情,删除作者,详情一定会被级联删除
        # 外键字段为正向查询字段,related_name是反向查询字段
        autor = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)
    

    3.2 ORM外键设计

    ​ 1、一对多:外键放在多的一方

    ​ 2、多对多:外键放在常用的一方

    ​ 3、一对一:外键放在不常用的一方

    ​ 4、外键字段为正向查询字段,related_name是反向查询字段

    四、连表序列化

    ​ serializers.py:

    class BookListSerializer(serializers.ListSerializer):
        # 1、create方法父级ListSerializer已经提供了
        # 2、父级ListSerializer没有通过update方法的实现体,需要重写
        def update(self, instance, validated_data):
            return [
                self.child.update(instance[i],attrs) for i,attrs in enumerate(validated_data)
            ]
        
    class BookModelSerializer(serializers.ListSerializer)
    	# 通过BookModelSerializer.Meta.list_serializer_class来访问绑定的ListSerializer
        class Meta:
            list_serializer_class = BookListSerializer
            model = moldes.Book
            # 序列化反序列化整合
            fields = ('name', 'price', 'publish_name', 'author_list', 'publish', 'authors')
            extra_kwargs = {
                'publish': {
                    'wite_only': Ture
                },
                'authors': {
                    'wite_only': Ture
                }
            }
            
    class PublishModelSerializer(serializers.ModelSerializer):
        # 子序列化都是提供给外键(正向方向)完成深度查询的,外键数据是唯一:many=False;不唯一:many=True
        # 注:只能参与序列化,且反序列化不能写(反序列化外键字段会抛异常)
        books = BookModelSerializer(many=True)
        class Meta:
            model = models.Publish
            field = ('name', 'address', 'books')
    

    五、单查群查序列化

    ​ views.py:

    class BookAPIView(APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                book_obj = models.Book.objects.filter(pk=pk, is_delete=False).first()
                if not book_obj:
                    return APIResponse(1, 'pk error', http_status=400)
                book_data = serializers.BookModelSerializer(book_obj).data
                return APIResponse(results=book_data)
            book_query = models.Book.objects.filter(is_delete=False).all()
            return APIResponse(0, 'ok', data=serializers.BookModelSerializer(book_query, many=True).data)
    

    六、单删群删接口

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            pks = [pk]
        else:
            pks = request.data.get('pks')
        if not pks:
            return APIResponse(1, 'delete error', http_status=400)
        rows = models.Book.objects.filter(is_delete=False, pk__in=pks).update(is_delete=Ture)
        if rows:
            return APIResponse(0,'delete ok')
        return APIResponse(1, 'delete failed')
    

    七、单增群增接口

    def post(self, request, *args, **kwargs):
        request_data = request.data
        # 单增
        if isinstance(request_data, dict)
        	book_ser = serializers.BookModelSerializer(data=request_data)
            if book_ser.is_valid():
                book_obj = book_ser.save()
                return APIResponse(results=serializers.BookModelsSerializer(book_obj).data)
            return APIResponse(1, msg=book_ser.errors)
        elif isinstance(request_data, list)and len(request_data) != 0: #群增 
            book_ser = serializers.BookModelSerializer(data=request_data, many=Ture)
            book_ser.is_valid(raise_exception=True)
            book_obj_list = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_obj_list, many=True).data)
            else:
                return APIResponse(1, 'data error', http_status=400)
    

    八、单整体改、群整体改

    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        request_data = request.data
        if pk:  # 单改
            try:
                book_obj = models.Book.objects.get(pk=pk)
            except:
                return APIResponse(1, 'pk error')
            # 修改和新增,都需要通过数据,数据依旧给data,修改与新增不同点,instance要被赋值为被修改对象
                book_ser = serializers.BookModelSerializer(instance=book_obj, data=request_data)
                book_ser.is_valid(raise_exception=True)
                book_obj = book_ser.save()
                return APIResponse(results=serializers.BookModelSerializer(book_obj).data)
        else:  # 群改
            if not isintance(request_data, list) or len(request_data) == 0:
                return APIResponse(1, 'data error', http_status=400)
            
            obj_list = []
            data_list = []
            for dic in request_data:
                try:
                    pk = dic.pop('pk')
                    try:
                        obj = models.Book.objects.get(pk=pk, is_delete=False)
                        obj_list.append(obj)
                        data_list.append(dic)
                    except:
                        pass
                except:
                    return APIResponse(1, 'data error', http_status=400)
    
            book_ser = serializers.BookModelSerializer(instance=obj_list, data=data_list, many=True)
            book_ser.is_valid(raise_exception=True)
            book_obj_list = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_obj_list, many=True).data)
    

    九、单局部与群局部修改

    def patch(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        request_data = request.data
        if pk:
            try:
                book_obj = models.Book.objects.get(pk=pk)
            except:
                return APIResponse(1, 'pk error')
            book_ser = serializers.BookModelSerializer(instance=book_obj, data=request_data, partial=Ture)
            book_ser.is_valid(raise_exception=Ture)
            book_obj = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_obj).data)
        
        else: # 群增
            if not isinstance(request_data, list) or len(request_data) == 0:
                return APIResponse(1, 'data error', http_status=400)
            # 注:一定不要在循环体中对循环对象进行增删(影响对象长度)的操作
            obj_list = []
            data_list = []
            for dic in request_data:
                # request_data可能是list,单内部不一定是dict
                try:
                    pk = dic.pop('pk')
                    try:
                        obj = models.Book.objects.get(pk=pk, is_delete=False)
                        obj_list.append(obj)
                        data_list.append(dic)
                    except:
                        pass
                except:
                    return APIResponse(1, 'data error', http_status=400)
    
            book_ser = serializers.BookModelSerializer(instance=obj_list, data=data_list, many=True, partial=True)
            book_ser.is_valid(raise_exception=True)
            book_obj_list = book_ser.save()
            return APIResponse(results=serializers.BookModelSerializer(book_obj_list, many=True).data)
    
    
  • 相关阅读:
    简单的结账功能(可用于各种结账)
    有关菜单进行“估清”的功能
    在线客服~~
    在windows下安装GIT
    GIT之二 基础篇(2)
    简单模仿javascript confirm方法的例子
    微信公众平台开发 第三篇
    微信公众平台开发 第二篇
    微信公众平台开发 第一篇
    GIT之二 基础篇(1)
  • 原文地址:https://www.cnblogs.com/tangceng/p/11909166.html
Copyright © 2011-2022 走看看