zoukankan      html  css  js  c++  java
  • drf序列化群增、群改、群删

    1 自定义user表,签发token,认证类

    表模型

    class MyUser(models.Model):
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=32)
        phone = models.CharField(max_length=32)
        email = models.EmailField()

    路由

    path('login2/', views.MyLoginView.as_view()),

    视图

    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    from rest_framework_jwt.views import obtain_jwt_token
    
    
    class MyLoginView(APIView):
        def post(self, request, *args, **kwargs):
            username = request.data.get('username')
            password = request.data.get('password')
            # 如果是手机号
            if re.match('^1[3-9]d{9}$', username):
                # 以手机号登录
                user = MyUser.objects.filter(phone=username).first()
            elif re.match('^.+@.+$', username):
                # 以邮箱登录
                user = MyUser.objects.filter(email=username).first()
            else:
                # 以用户名登录
                user = MyUser.objects.filter(username=username).first()
            # 如果user有值并且密码正确
            if user and user.password == password:
                # 登录成功,生成token
                # drf-jwt中有通过user对象生成token的方法
                payload = jwt_payload_handler(user)
                token = jwt_encode_handler(payload)
                return APIResponse(token=token, username=user.username)
            else:
                return APIResponse(code=101, msg='用户名或密码错误')

    2 book,publish,author表关系及抽象表建立

    # 注意:以后所有的数据删除,尽量用软删除,使用一个字段标志是否删除,而不是真正的从数据库中删除
        -好处:1 这样删除数据不会影响索引,不会导致索引失效
              2 之前存的用户数据还在,以备以后使用
    # 表模型如下
    # 抽象出一个基表(不再数据库生成,abstract=True),只用来继承
    
    class BaseModel(models.Model):
        is_delete = models.BooleanField(default=False)
        create_time = models.DateTimeField(auto_now_add=True)
    
        class Meta:
            # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
            abstract = True
    
    
    class Book(BaseModel):
        name = models.CharField(max_length=16)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish = models.ForeignKey(to='Publish', db_constraint=False, on_delete=models.DO_NOTHING)
        # 重点:多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联
        # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表
        authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)
    
        @property
        def publish_name(self):
            return self.publish.name
        @property
        def author_list(self):
            # ll=[]
            # for author in self.authors.all():
            #     ll.append({'name':author.name,'sex':author.get_sex_display()})
            return [{'name': author.name, 'sex': author.get_sex_display()} for author in self.authors.all()]
    
    
    class Publish(BaseModel):
        name = models.CharField(max_length=16)
        address = models.CharField(max_length=64)
    
    
    class Author(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是反向查询字段
        author = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)

    3 book表单增群增

    class BookView(APIView):
        def post(self, request, *args, **kwargs):
            if isinstance(request.data, dict):
                # 增一条
                ser = serializer.BookSerializer(data=request.data)
                ser.is_valid(raise_exception=True)
                ser.save()
                return APIResponse(data=ser.data)
            elif isinstance(request.data, list):
                # 增多条
                ser = serializer.BookSerializer(data=request.data, many=True)
                # 内部如何实现的?
                # many=True,ser不是BookSerializer对象,而是ListSerializer对象,套了一个个的BookSerializer
                print(type(ser))
                ser.is_valid(raise_exception=True)
                #
                from rest_framework.serializers import ListSerializer
                ser.save()  # ListSerializer的save
                return APIResponse(msg='增加%s条成功' % len(request.data))

    4 book表单查群查

    class BookView(APIView):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk', None)
            if pk:
                # 单查
                # 方式一
                # book=models.Book.objects.filter(id=pk).filter(is_delete=False).first()
                # if not book:
                #     raise Exception('要查询的不存在')
    
                # 方式二
                book = models.Book.objects.get(id=pk, is_delete=False)
                ser = serializer.BookSerializer(instance=book)
    
            else:
                # 查所有
                book_list = models.Book.objects.all().filter(is_delete=False)
                ser = serializer.BookSerializer(instance=book_list, many=True)
            return APIResponse(data=ser.data)

    5 book表单改群改

    class BookView(APIView):
        def put(self, request, *args, **kwargs):
            pk = kwargs.get('pk', None)
            if pk:
                # 单条修改
                book = models.Book.objects.get(id=pk, is_delete=False)
                ser = serializer.BookSerializer(instance=book, data=request.data)
                ser.is_valid(raise_exception=True)
                ser.save()
                return APIResponse(msg='修改成功')
            else:
                # 分析:ListSerializer的update方法没有写,需要我们自己写
                from rest_framework.serializers import ListSerializer
                # pks=[item['id'] for item in request.data]
    
                # 如果不重写ListSerializer的update方法,这是存不进去的
                pks = []
                for item in request.data:
                    pks.append(item['id'])
                    item.pop('id')
    
                print(request.data)
                book_list = models.Book.objects.filter(id__in=pks, is_delete=False)
                ser = serializer.BookSerializer(instance=book_list, data=request.data, many=True)
                print(type(ser))
                ser.is_valid(raise_exception=True)
                ser.save()
                return APIResponse(msg='修改%s条成功')
    
                # 你们能想到的方法
                # pks = []
                # for item in request.data:
                #     pks.append(item['id'])
                #     item.pop('id')
                # book_list = models.Book.objects.filter(id__in=pks, is_delete=False)
                #
                # for i,book in enumerate(book_list):
                #     ser = serializer.BookSerializer(instance=book, data=request.data[i])
                #     ser.is_valid(raise_exception=True)
                #     ser.save()
                # return APIResponse(msg='修改%s条成功'%len(book_list))

    6 book表的单删群删

    class BookView(APIView):
    
        def delete(self, request, *args, **kwargs):
            pk = kwargs.get('pk', None)
            pks = []
            if pk:
                # 单条删除
                # res=models.Book.objects.filter(id=pk).update(is_delete=True)
                # print(res)
                # return APIResponse(msg='删除成功')
                pks.append(pk)
            else:
                pks = request.data
    
            res = models.Book.objects.filter(id__in=pks).update(is_delete=True)
            if res >= 1:
                return APIResponse(msg='删除%s条成功' % res)
            else:
                # raise Exception('没有要删除的数据')
                return APIResponse(code=999, msg='没有要删除的数据')

    7 序列化类

    from app01 import models
    
    
    class ListBookSerializer(serializers.ListSerializer):
        # def create(self, validated_data):
        #     print('=======',validated_data)
        #     return '1'
        def update(self, instance, validated_data):
            print(instance) # book_list:是一堆图书对象
            print(validated_data) # 列表套字典,是要修改的数据
    
            return [self.child.update(book, validated_data[i]) for i, book in enumerate(instance)]
    
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            list_serializer_class=ListBookSerializer # 指定many=True的时候,生成的ListBookSerializer的对象了
            fields = ['name', 'price', 'publish', 'authors', 'publish_name', 'author_list']
            extra_kwargs = {
                'publish': {'write_only': True},
                'authors': {'write_only': True},
                'publish_name': {'read_only': True},
                'author_list': {'read_only': True},
    
            }
    
        # def create(self, validated_data):
        #     print(validated_data)

    路由

    path('books/', views.BookView.as_view()),
    re_path('books/(?P<pk>d+)', views.BookView.as_view()),
    1 自定义token的签发和认证:https://www.cnblogs.com/liuqingzheng/articles/9766397.html
    每天逼着自己写点东西,终有一天会为自己的变化感动的。这是一个潜移默化的过程,每天坚持编编故事,自己不知不觉就会拥有故事人物的特质的。 Explicit is better than implicit.(清楚优于含糊)
  • 相关阅读:
    【转】ListView,GridView之LayoutAnimation特殊动画的实现 ps:需要学习的是在getView中添加动画的思想
    自定义Dialog
    android 横向list特效——规格滑动
    android BaseAdapter优化
    自定义弧形进度条
    滑块闹钟界面
    HTML学习10
    HTML学习9
    HTML学习8
    HTML学习7
  • 原文地址:https://www.cnblogs.com/kylin5201314/p/14938892.html
Copyright © 2011-2022 走看看