ModelSerializer字段验证的扩展操作

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

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('已有出价更高者,请调整出价')
        return value

重构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

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

'''
此处涉及到两个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
        }
posted @ 2020-03-04 18:11  阿浪阿浪  阅读(451)  评论(0编辑  收藏  举报