zoukankan      html  css  js  c++  java
  • ModelViewSet序列化限流排序

    def validate_字段名(self, value),单一字段校验

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    from rest_framework import serializers
    from rest_framework import exceptions
    from .. import models
     
    class BidModelSerializer(serializers.ModelSerializer):
        username = serializers.CharField(source='user.nickname', read_only=True)
        status_text = serializers.CharField(source='get_status_display', read_only=True)
     
        class Meta:
            model = models.BidRecord
            exclude = ['user', 'status', ]
     
        def validate_item(self, value):
            """ 验证是否还正在拍卖"""
            item_id = self.initial_data.get('item')
            exists = models.AuctionItem.objects.filter(id=item_id, status=3).exists()
            if not exists:
                raise exceptions.ValidationError('拍卖商品不存在或已成交')
            return value
     
        def validate_price(self, value):
            """ 验证价格
            1. 比最大的要大
            2. 是单元的倍数
            """
            from django.db.models import Max
            item_id = self.initial_data.get('item')
            item_object = models.AuctionItem.objects.filter(id=item_id).first()
            if value < item_object.start_price:
                raise exceptions.ValidationError('出价不能低于低价')
            result = models.BidRecord.objects.filter(item_id=item_id).aggregate(max_price=Max('price'))
            if not result['max_price']:
                return value
            if value <= result['max_price']:
                raise exceptions.ValidationError('已有出价更高者,请调整出价')

      

    重构create方法

    复制代码
    复制代码
    '''
    这里应用了Serializer与ModelSerializer的结合使用
    
    '''
    class CreateNewsTopicModelSerializer(serializers.Serializer):
        key = serializers.CharField()
        cos_path = serializers.CharField()
    
    
    class CreateNewsModelSerializer(serializers.ModelSerializer):
        imageList = CreateNewsTopicModelSerializer(many=True)
    
        class Meta:
            model = models.News
            exclude = ['user', 'viewer_count', 'comment_count']
    
        def create(self, validated_data):
            image_list = validated_data.pop('imageList')
            news_object = models.News.objects.create(**validated_data)
            data_list = models.NewsDetail.objects.bulk_create(
                [models.NewsDetail(**info, news=news_object) for info in image_list]
            )
            news_object.imageList = data_list
            if news_object.topic:
                models.Topic.objects.filter(id=news_object.topic_id).update(count=F('count') + 1)
            return news_object
    复制代码
    复制代码

     

    自定义字段,获取一张表的全部内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    '''
    此处涉及到两个ModelSerializer类
     
    # 保证金
    deposit = serializers.SerializerMethodField()
     
    def get_deposit(self, obj):
        return PayDepositModelSerializer(instance=obj.deposit).data
     
    '''
             
    class PayDepositModelSerializer(serializers.ModelSerializer):
     
        # 支付保证金
        deposit_text = serializers.CharField(source='get_deposit_type_display')
        checked = serializers.BooleanField(default=False)
     
        class Meta:
            model = models.Collateral
            fields = ['id', 'deposit_type', 'deposit_text', 'amount', 'balance', 'checked']
     
     
    class PayModelSerializer(serializers.ModelSerializer):
     
        user_balance = serializers.IntegerField(source='user.balance')
     
        auction = serializers.CharField(source='lot.special_auction_id')
     
        # 拍品
        lot = serializers.SerializerMethodField()
     
        # 保证金
        deposit = serializers.SerializerMethodField()
     
        # 是否有优惠券
        coupon = serializers.SerializerMethodField()
     
        # 支付方式
        pay_method = serializers.SerializerMethodField()
     
        class Meta:
            model = models.Order
            exclude = ['uid', 'twenty_four_task_id', 'user']
     
        def get_deposit(self, obj):
            return Pay DepositModelSerializer(instance=obj.deposit).data
     
        def get_coupon(self, obj):
            user_object = self.context['request'].user
            exists = models.UserCoupon.objects.filter(
                user=user_object, status=1, coupon__auction=obj.lot.special_auction_id).exists()
     
            context = {
                'id': None,
                'has': exists,
                'text': '请选择优惠券' if exists else '无',
                'money': 0
            }
            return context
     
        def get_pay_method(self, obj):
            balance = self.context['request'].user.balance
            info = {
                'selected': 1,
                'choices': [
                    {'id': 1, 'text': '余额(%s)' % balance},
                    {'id': 2, 'text': '微信支付'},
                ]
            }
            return info
     
        def get_lot(self, obj):
            return {
                'title': obj.lot.name,
                'cover': obj.lot.cover.name,
                'uid': obj.lot.catalog_num
            }

      

    ModelSerializer序列化与反序列化(重点)

    视图类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    class UserV3APIView(APIView):
        # 单查群查
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:
                user_obj = models.User.objects.filter(is_delete=False, pk=pk).first()
                if not user_obj:
                    return Response({
                        'status': 1,
                        'msg': 'pk error',
                    }, status=400)
     
                user_ser = serializers.UserModelSerializer(user_obj, many=False)
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': user_ser.data
                })
            else:
                user_query = models.User.objects.filter(is_delete=False).all()
     
                user_ser = serializers.UserModelSerializer(user_query, many=True)
     
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': user_ser.data
                })
     
        # 单增
        def post(self, request, *args, **kwargs):
            user_ser = serializers.UserModelSerializer(data=request.data)
            if user_ser.is_valid():
                # 入库
                user_obj = user_ser.save()
                return Response({
                    'status': 0,
                    'msg': 'ok',
                    'results': serializers.UserModelSerializer(user_obj).data
                })
            else:
                return Response({
                    'status': 1,
                    'msg': user_ser.errors,
                })

      

    序列化类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    """ ModelSerializer类序列化与反序列化总结
    1)序列化类继承ModelSerializer,所以需要在配置类Meta中进行配置
    2)model配置:绑定序列化相关的Model表
    3)fields配置:采用 插拔式 设置所有参与序列化与反序列化字段
    4)extra_kwargs配置:
        划分系统字段为三种:只读(read_only)、只写(write_only)、可读可写(不设置)
        字段是否必须:required
        选填字段:在extra_kwargs进行配置,但不设置required,且有默认值
    5)自定义序列化字段:
        第一种(不提倡):在序列化类中用SerializerMethodField()来实现
        第二种(提倡):在模型类中用@property来实现,可插拔
    6)自定义反序列化字段:
        同Serializer类,且规则只能在此声明中设置,或是在钩子中设置,在extra_kwargs中对其设置的无效
        自定义反序列化字段与系统字段,设置规则一样,所以必须设置 write_only
    7)局部钩子,全局钩子同Serializer类
    8)不需要重写create和update方法
    """
    class UserModelSerializer(serializers.ModelSerializer):
        # 第一种自定义序列化字段:该字段必须在fields中设置
        # gender = serializers.SerializerMethodField()
        # def get_gender(self, obj):
        #     return obj.get_sex_display()
     
     
        # 自定义反序列化字段同Serializer类,且规则只能在此声明中设置,或是在钩子中设置,
        #       在extra_kwargs中对其设置的无效
        # 注:自定义反序列化字段与系统字段,设置规则一样,所以必须设置 write_only
        re_password = serializers.CharField(min_length=3, max_length=16, write_only=True)
     
        class Meta:
            model = models.User
            # fields采用 插拔式 设置所有参与序列化与反序列化字段
            fields = ('username', 'gender', 'icon', 'password', 'sex', 're_password')
            extra_kwargs = {
                'username': {  # 系统字段不设置read_only和write_only,默认都参加
                    'min_length': 3,
                    'max_length': 10,
                    'error_messages': {
                        'min_length': '太短',
                        'max_length': '太长'
                    }
                },
                'gender': {
                    'read_only': True,  # 自定义的序列化字段默认就是read_only,且不能修改,可以省略
                },
                'password': {
                    'write_only': True,
                },
                'sex': {  # 像sex有默认值的字段,为选填字段('required': True可以将其变为必填字段)
                    'write_only': True,
                    # 'required': True
                }
            }
     
     
        # 局部全局钩子同Serializer类,是与 Meta 同缩进的
        def validate_username(self, value):
            if 'g' in value.lower():
                raise serializers.ValidationError('名字中不能有g')
            return value
     
        def validate(self, attrs):
            password = attrs.get('password')
            re_password = attrs.pop('re_password')
            if password != re_password:
                raise serializers.ValidationError({'re_password': '两次密码不一致'})
            return attrs
     
        # create和update方法不需要再重写,ModelSerializer类已提供,且支持所有关系下的连表操作

      

    模型类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    from django.db import models
     
    class User(models.Model):
        SEX_CHOICES = (
            (0, '女'),
            (1, '男'),
        )
     
        username = models.CharField(max_length=64, verbose_name='用户名', blank=True, unique=True)
        password = models.CharField(max_length=64, verbose_name='密码')
        sex = models.IntegerField(choices=SEX_CHOICES, default=0, verbose_name='性别')
        img = models.ImageField(upload_to='img', default='img/default.png', verbose_name='头像')
        # 开发中,数据不会直接删除,通过字段控制
        is_delete = models.BooleanField(default=False, verbose_name='是否注销')
        # 数据库数据入库,一般都会记录该数据第一次入库时间,有时候还会记录最后一次更新时间
        created_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
     
        # 第二种自定义序列化字段(插拔式,提倡使用)
        @property
        def gender(self):
            return self.get_sex_display()
     
        @property
        def icon(self):
            from django.conf import settings
            return '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, self.img)
     
     
        class Meta:  # 配置类,给所属类提供配置信息
            db_table = 'old_boy_user'
            verbose_name_plural = '用户表'
     
        def __str__(self):  # 不要在这里进行连表操作,比如admin页面可能会崩溃
            return self.username
  • 相关阅读:
    web服务器-Apache
    nginx优化
    nginx下载限速
    nginx-URL重写
    HDU 5358 First One 求和(序列求和,优化)
    HDU 5360 Hiking 登山 (优先队列,排序)
    HDU 5353 Average 糖果分配(模拟,图)
    UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
    HDU 5348 MZL's endless loop 给边定向(欧拉回路,最大流)
    HDU 5344 MZL's xor (水题)
  • 原文地址:https://www.cnblogs.com/lcj-momo/p/13893883.html
Copyright © 2011-2022 走看看