序列化第三张表的数据

import logging
import re
import json
import datetime
# from cryptography.utils import cached_property
from django.utils.functional import cached_property

from django.db.models import Q, Sum, Count
from rest_framework import serializers
from rest_framework import exceptions
from xqcircle.models import CircleUser, CityOfCircle, Circle, Circle2CircleUser, Dynamic, GroupBuy, Conversation, 
    Message, Config, GroupBuyForm, RecommRules, Like, CutKnife, GrouopOwner, Recommend, RealUserInformation, 
    AcademicCertificateRecord, Crowdordering, Order, Matchmaker, IdentifyingCode, MatchmakerAreaConfig, 
    IncomeAndExpenditure
from xqcircle import constants
from xqcircle import utils
from django.conf import settings
from xqcircle import tasks as ts

logger = logging.getLogger()


class CircleUserListSerializer(serializers.ListSerializer):
    @property
    def data(self):
        ret = super(CircleUserListSerializer, self).data
        for _ in ret:
            photos_str = ''.join(_['photos']).strip(',')
            if not photos_str:
                _['photos'] = []
            else:
                _['photos'] = photos_str.split(',')
        return ret


class CircleUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = CircleUser
        list_serializer_class = CircleUserListSerializer
        # fields = "__all__"
        exclude = ['app_id', 'session_key', 'visible_quantity', 'user_status', 'open_id', 'open_gid',
                   'member_expire_time', 'last_login_time', 'last_city', 'create_time']

    # phone = serializers.CharField(max_length=11, required=True, error_messages={
    #     'max_length': 'Phone number length exceeds 11',
    #     'required': "Phone value can not be empty"
    # })
    # career = serializers.CharField(max_length=128, required=True, error_messages={
    #     'max_length': "Career value length exceeds 128",
    #     'required': "Career value can not be empty"
    # })
    # child_introduction = serializers.CharField(max_length=140, required=True,
    #                                            error_messages={
    #                                                'max_length': "Child_introduction value length exceeds 140",
    #                                                'required': "Child_introduction value can not be empty"
    #                                            })
    marriage = serializers.SerializerMethodField()
    spouse_description = serializers.CharField(max_length=140, required=False, allow_blank=True,
                                               error_messages={
                                                   'max_length': "Spouse_description value length exceeds 140",
                                               })

    # photos = serializers.ListField(required=True, error_messages={
    #     'required': "Photos value can not be empty"
    # })

    def get_marriage(self, obj):
        return constants.MARITAL_STATUS[obj.marriage]

    # def validate_phone(self, attrs):
    #     r = re.compile(r"^1((3[0-9])|(4[5,7])|(5[0-3,5-9])|(7[0,3,5-8])|(8[0-9])|66|98|99|47)d{8}")
    #     if not isinstance(attrs, str):
    #         raise exceptions.ValidationError("Phone number type error")
    #     if not r.match(attrs):
    #         raise exceptions.ValidationError("Phone number is error")
    #     return attrs
    #
    # def validate_career(self, attrs):
    #     if not isinstance(attrs, str):
    #         raise exceptions.ValidationError("Career value type error")
    #     return attrs
    #
    # def validate_child_introduction(self, attrs):
    #     if not isinstance(attrs, str):
    #         raise exceptions.ValidationError("Child_introduction value type error")
    #     return attrs

    # def validate_photos(self, attrs):
    #     if not isinstance(attrs, list):
    #         raise exceptions.ValidationError("Photos value type error")
    #     if not attrs:
    #         raise exceptions.ValidationError("Photos value can not be empty")
    #     url_complie = re.compile(r'(http|https)://[w-_]+(.[w-_]+)+([w-.,@?^=%&:/~+#]*[w-@?^=%&/~+#])?')
    #     for _ in attrs:
    #         if not url_complie.match(_):
    #             raise exceptions.ValidationError("Photo url is error")
    #     return attrs

    @property
    def data(self):
        ret = super(CircleUserSerializer, self).data
        if isinstance(ret, dict):
            photos_str = ''.join(ret['photos']).strip(',')
            if not photos_str:
                ret['photos'] = []
            else:
                ret['photos'] = photos_str.split(',')
        return ret


class CircleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Circle
        fields = ('id', 'circle_name', 'member_number', 'heat', 'dynamic_number', 'dynamics', 'advertising',
                  'circle_info', 'single_buy_by_android', 'joined', 'members', 'slogan', 'link_path')

    members = serializers.SerializerMethodField()
    dynamics = serializers.SerializerMethodField()
    advertising = serializers.SerializerMethodField()
    circle_info = serializers.SerializerMethodField()
    joined = serializers.SerializerMethodField()
    slogan = serializers.SerializerMethodField()
    link_path = serializers.SerializerMethodField()

    def get_members(self, obj):
        res = []
        host = Circle2CircleUser.objects.filter(circle_id=obj.id, user_type=0).values('user__career',
                                                                                      'user__avatar').first()
        if host:
            res.append(host)
        members = Circle2CircleUser.objects.filter(circle_id=obj.pk, user_type=1, user__card=True).values(
            'user__career',
            'user__avatar').order_by('-create_time')[:3]
        res.extend(members)
        return res

    def get_dynamics(self, obj):
        try:
            dynamics = Dynamic.objects.filter(circle_id=obj.id).order_by(
                '-weight_h')[:10]
            serializer = DynamicsSerializer(dynamics, many=True)
        except Dynamic.DoesNotExist:
            return []
        return serializer.data

    def get_advertising(self, obj):
        group_config = Config.objects.filter(itype='wechat_advertising', ikey='circle_{}'.format(obj.pk),
                                             ienable=1).values("ival")[0:2]

        try:
            return [json.loads(group['ival']) for group in group_config]
        except:
            logger.info("群广告配置错误")
            return []

    def get_circle_info(self, obj):
        """
        圈子介绍语,口号,标签信息
        """
        ikey = "circle_{}".format(obj.id)
        circle_config = Config.objects.filter(itype='group_advertising', ikey=ikey, ienable=1).order_by('-id').values(
            "ival").first()
        if not circle_config:
            logger.info('圈子 {} 缺少标签,介绍语等信息')
            return {}
        else:
            try:
                return json.loads(circle_config['ival'])
            except:
                logger.info("{} 圈子标签配置信息json解析错误".format(obj.id))
                return {}

    def get_joined(self, obj):
        joined = Circle2CircleUser.objects.filter(circle_id=obj.id, user__card=True).values('user_id',
                                                                                            'user__career',
                                                                                            'user__avatar')[:20]
        return joined

        # place_of_residence = user.place_of_residence
        # logger.info('{} {}'.format(user.pk, place_of_residence))
        # if place_of_residence:
        #     try:
        #         provice, city = place_of_residence.split('-')
        #     except:
        #         logger.info('{} 格式错误'.format(place_of_residence))
        #         provice = city = '上海'
        # else:
        #     provice = city = '上海'
        # ikey = provice if provice in constants.MUNICIPALITY else city
        # banner_config = Config.objects.filter(itype='circle_banner', ikey=ikey)[0:3]
        # if not banner_config:
        #     logger.info('{} 缺少该城市的banner配置')
        #     banner_config = Config.objects.filter(itype='circle_banner', ikey='上海')[0:3]
        #
        # try:
        #     return [json.loads(item.ival) for item in banner_config]
        # except:
        #     logger.info('{} banner解析出错'.format(banner_config))
        #     return []

    def get_slogan(self, obj):
        """
        圈子介绍语,口号,标签信息
        """
        ikey = "circle_{}".format(obj.id)
        circle_config = Config.objects.filter(itype='group_advertising', ikey=ikey, ienable=1).order_by('-id').values(
            "ival").first()
        if not circle_config:
            logger.info('圈子 {} 缺少标签,介绍语等信息')
            return 0
        else:
            try:
                return json.loads(circle_config['ival'])['slogan']
            except:
                logger.info("{} 圈子标签配置信息json解析错误".format(obj.id))
                return 0

    def get_link_path(self, obj):
        group_config = utils.get_circle_group_config(obj.pk)
        if group_config:
            return group_config['link_path']
        else:
            return ''


class CirclesSerializer(serializers.ModelSerializer):
    intro = serializers.SerializerMethodField()  # 圈子介绍
    is_in = serializers.SerializerMethodField()  # 用户是否在圈内

    class Meta:
        model = Circle
        fields = (
            'id', 'circle_name', 'intro', 'circle_description', 'member_number', 'heat', 'dynamic_number', 'image',
            'is_in')

    def get_intro(self, obj):
        ikey = "circle_%d" % obj.id
        circle_config = Config.objects.filter(itype='group_advertising', ikey=ikey, ienable=1).order_by('-id').first()

        if circle_config:
            try:
                return json.loads(circle_config.ival)['intro']
            except:
                logger.info('{} 圈子解析配置出错')
                return ''
        else:
            logger.info('{} 圈子缺少相关标签配置'.format(obj.id))
            return ''

    def get_is_in(self, obj):
        return Circle2CircleUser.objects.filter(circle_id=obj.pk, user=self.context['request'].user).exists()


class GroupBuySerializer(serializers.ModelSerializer):
    class Meta:
        model = GroupBuy
        fields = '__all__'


class DynamicsListSerializer(serializers.ListSerializer):
    @property
    def data(self):
        ret = super(DynamicsListSerializer, self).data
        for _ in ret:
            _['user_id'] = _['user']
            _['circle_id'] = _['circle']
            del _['user']
            del _['circle']
            photos_str = ''.join(_['photos']).strip(',')
            if not photos_str:
                _['photos'] = []
            else:
                _['photos'] = photos_str.split(',')
        return ret


class DynamicsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Dynamic
        list_serializer_class = DynamicsListSerializer
        exclude = ["create_time", "weight_a", "weight_v", "weight_h"]

    circle = serializers.IntegerField(source='circle.pk', error_messages={
        'required': "Circle value can not be empty",
    })
    user = serializers.CharField(source='user.pk', error_messages={
        'required': "User value can not be empty",
    })
    detail = serializers.CharField(max_length=140, required=False, allow_blank=True, error_messages={
        'max_length': "Detail value length exceeds 140",
    })
    photos = serializers.ListField(required=False)
    career = serializers.SerializerMethodField()
    avatar = serializers.SerializerMethodField()
    age = serializers.SerializerMethodField()
    gender = serializers.SerializerMethodField()

    def validate_circle(self, attrs):
        try:
            attrs = Circle.objects.get(pk=attrs)
        except Circle.DoesNotExist:
            raise exceptions.ValidationError("Circle value is error")
        return attrs

    def validate_user(self, attrs):
        try:
            attrs = CircleUser.objects.get(pk=attrs)
        except CircleUser.DoesNotExist:
            raise exceptions.ValidationError("User value is error")
        return attrs

    def validate_photos(self, attrs):
        if not isinstance(attrs, list):
            raise exceptions.ValidationError("Photos value type error")
        url_complie = re.compile('(http|https)://[w-_]+(.[w-_]+)+([w-.,@?^=%&:/~+#]*[w-@?^=%&/~+#])?')
        for _ in attrs:
            if not url_complie.match(_):
                raise exceptions.ValidationError("Photo url is error")
        return ','.join(attrs)

    def validate(self, attrs):
        if not attrs['detail'] and not attrs['photos']:
            raise exceptions.ValidationError("Detail and Photos cannot be empty at the same time")
        return attrs

    def get_career(self, obj):
        return obj.user.career

    def get_avatar(self, obj):
        return obj.user.avatar

    def get_age(self, obj):
        return obj.user.age

    def get_gender(self, obj):
        return obj.user.gender

    @property
    def data(self):
        ret = super(DynamicsSerializer, self).data
        if isinstance(ret, dict):
            ret['user_id'] = ret['user']
            ret['circle_id'] = ret['circle']
            photos_str = ''.join(ret['photos']).strip(',')
            if not photos_str:
                ret['photos'] = []
            else:
                ret['photos'] = photos_str.split(',')
            del ret['user']
            del ret['circle']
        return ret

    def create(self, validated_data):
        validated_data['circle'] = validated_data['circle']['pk']
        validated_data['user'] = validated_data['user']['pk']
        return Dynamic.objects.create(**validated_data)


class ConversationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Conversation
        # list_serializer_class = DynamicsListSerializer
        fields = '__all__'

    user_1_info = serializers.SerializerMethodField()
    user_2_info = serializers.SerializerMethodField()
    last_message = serializers.SerializerMethodField()
    unread_count = serializers.SerializerMethodField()
    circle_id = serializers.SerializerMethodField()
    circle_name = serializers.SerializerMethodField()
    fake_uid = serializers.SerializerMethodField()

    def get_user_1_info(self, obj):
        try:
            res = CircleUser.objects.filter(user_id=obj.user_1_id).values('avatar', 'age', 'career').first()
        except CircleUser.DoesNotExist:
            return {}
        return res

    def get_user_2_info(self, obj):
        try:
            res = CircleUser.objects.filter(user_id=obj.user_2_id).values('avatar', 'age', 'career').first()
        except CircleUser.DoesNotExist:
            return {}
        return res

    def get_last_message(self, obj):
        if self.context['request'].user.pk == obj.user_1_id:
            return obj.last_message or ''
        else:
            return obj.last_message_2 or ''

    def get_unread_count(self, obj):
        if self.context['request'].user.pk == obj.user_1_id:
            send_user_id = obj.user_2_id
            receive_user_id = obj.user_1_id
        else:
            send_user_id = obj.user_1_id
            receive_user_id = obj.user_2_id

        cur_time = datetime.datetime.now()
        s_time = cur_time - datetime.timedelta(days=7)
        count = Message.objects.filter(send_user_id=send_user_id, receive_user_id=receive_user_id, is_effective=True,
                                       state=False).filter(create_time__range=(s_time, cur_time)).count()
        return min(99, count) or ''

    def get_circle_id(self, obj):
        if self.context['request'].user.pk == obj.user_1_id:
            user_id = obj.user_2_id
        else:
            user_id = obj.user_1_id

        circle = utils.get_most_expensive_circle_belong(user_id)
        if circle:
            return circle.pk
        else:
            return -1

    def get_circle_name(self, obj):
        if self.context['request'].user.pk == obj.user_1_id:
            user_id = obj.user_2_id
        else:
            user_id = obj.user_1_id

        circle = utils.get_most_expensive_circle_belong(user_id)
        if circle:
            return circle.circle_name
        else:
            return ''

    def get_fake_uid(self, obj):
        if self.context['request'].user.pk == obj.user_1_id:
            user_id = obj.user_2_id
        else:
            user_id = obj.user_1_id
        return utils.encrypt_uid(user_id)


class MessageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Message
        # list_serializer_class = DynamicsListSerializer
        fields = '__all__'


class CityOfCircleSerializer(serializers.ModelSerializer):
    class Meta:
        model = CityOfCircle
        # list_serializer_class = DynamicsListSerializer
        # fields = '__all__'
        fields = ('city_name', 'id', 'parent_id')


class ConfigsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Config
        # list_serializer_class = DynamicsListSerializer
        fields = '__all__'


class GroupBuyFormSerializer(serializers.ModelSerializer):
    class Meta:
        model = GroupBuyForm
        # list_serializer_class = DynamicsListSerializer
        fields = '__all__'


class RecommStandardSerializer(serializers.ModelSerializer):
    class Meta:
        model = RecommRules
        fields = '__all__'


class UserLikeSerializer(serializers.ModelSerializer):
    conversation_id = serializers.SerializerMethodField()

    def get_conversation_id(self, obj):
        conversation = Conversation.objects.filter(
            Q(user_1_id=obj.from_user_id, user_2_id=obj.to_user_id) | Q(user_1_id=obj.from_user_id,
                                                                        user_2_id=obj.to_user_id)).first()
        if conversation and obj.is_like:
            return conversation.pk
        return -1

    class Meta:
        model = Like
        fields = ('to_user_id', 'is_like', 'conversation_id')


class LikeMeUserSerizlizer(serializers.ModelSerializer):
    age = serializers.SerializerMethodField()

    class Meta:
        model = CircleUser
        fields = ('user_id', 'open_id', 'create_time', 'gender', 'age', 'place_of_residence', 'education', 'avatar',
                  'career', 'card')

    def get_age(self, obj):
        return obj.age[0:4]


class MembersSerializer(serializers.ModelSerializer):
    class Meta:
        model = CircleUser
        fields = ('user_id', 'open_id', 'gender', 'age', 'place_of_residence', 'education', 'avatar', 'career', 'card')


class ProfileSerializer(serializers.ModelSerializer):
    like_count = serializers.SerializerMethodField()  # 我喜欢的用户数量
    be_like_count = serializers.SerializerMethodField()  # 喜欢我的用户数量
    info_degree = serializers.SerializerMethodField()  # 个人资料完整度
    intro_degree = serializers.SerializerMethodField()  # 我的介绍完整度
    claim_id = serializers.SerializerMethodField()
    cut_group = serializers.SerializerMethodField()
    is_real = serializers.SerializerMethodField()  # 是否实名
    is_phone_auth = serializers.SerializerMethodField()  # 是否手机号认证
    is_full = serializers.SerializerMethodField()  # 必填资料是否全部填写
    is_union_id = serializers.SerializerMethodField()  # 是否获取 union_id
    user_type = serializers.SerializerMethodField()  # 用户类型
    fake_uid = serializers.SerializerMethodField()  # 虚拟用户ID
    is_education = serializers.SerializerMethodField()  # 是否学历认证
    user_group_type = serializers.SerializerMethodField()  # 是否是红娘

    class Meta:
        model = CircleUser
        fields = (
            'user_id', 'career', 'avatar', 'like_count', 'be_like_count', 'total_money', 'info_degree', 'intro_degree',
            'wechat_id', 'claim_id', 'cut_group', 'is_real', 'is_phone_auth', 'gender', 'age', 'place_of_residence',
            'is_full', 'is_wechat_visible', 'is_union_id', 'user_type', 'fake_uid', 'is_education', 'user_group_type')

    def get_like_count(self, obj):
        return Like.objects.filter(from_user_id=obj.user_id, is_like=True).count()

    def get_be_like_count(self, obj):
        user_type = utils.get_user_membership_type(obj)
        if user_type == 0:
            return Like.objects.filter(to_user_id=obj.user_id, is_like=True).count()
        elif utils.is_required_information(obj):
            # 如果未填写基本资料,则为0
            return constants.VISITOR_NUMBER
        else:
            return 0

    def get_info_degree(self, obj):
        """个人资料完整度
        基本信息:六项,每一项填写权重为10。
        性别、出生年月、学历、居住地、职业、身高。
        补充信息:五项,每一项填写权重为8。
        户籍、住房情况、月收入、婚姻状况、车辆状况。
        """
        options = (
            'gender', 'age', 'education', 'place_of_residence', 'career', 'height', 'residence', 'house',
            'monthly_salary', 'marriage', 'car')
        proportion = (10,) * 6 + (8,) * 5

        return sum(proportion[index] if getattr(obj, choice) else 0 for index, choice in enumerate(options))

    def get_intro_degree(self, obj):
        """我的介绍完整度
        文字描述:每一项填写权重为10。
        我的介绍、兴趣爱好、感情观、心仪的TA
        上传生活照:1张照片权重为20,最多累计权重为 60 。
        即用户上传3张照片或9张照片,总权重最多为60。
        """
        options = ('child_introduction', 'hobbies', 'emotional_view', 'spouse_description')
        proportion = (10,) * 4

        photos = obj.photos.split(',') if obj.photos else []

        # 生活照得分
        photos_degree = min(60, 20 * sum(1 for p in photos if p.strip()))

        return sum(
            proportion[index] if getattr(obj, choice) else 0 for index, choice in enumerate(options)) + photos_degree

    def get_claim_id(self, obj):
        group_owner = GrouopOwner.objects.filter(user_id=obj.user_id).first()

        return group_owner.pk if group_owner else ''

    def get_cut_group(self, obj):
        return CutKnife.objects.filter(user_id=obj.user_id, state=1, expire_time__gte=datetime.datetime.now()).values(
            'id', 'circle_id', 'circle_name', 'expire_time')

    def get_is_real(self, obj):
        # return all([obj.real_name, obj.id_card])
        return RealUserInformation.objects.filter(user_id=obj.pk).exists()

    def get_is_phone_auth(self, obj):
        return obj.phone != ''

    def get_is_full(self, obj):
        return all([obj.gender, obj.age, obj.education, obj.place_of_residence, obj.height, obj.career])

    def get_is_union_id(self, obj):
        return True if obj.union_id else False

    def get_user_type(self, obj):
        return utils.get_user_membership_type(obj)

    def get_fake_uid(self, obj):
        return utils.encrypt_uid(obj.pk)

    def get_is_education(self, obj):
        education_record = AcademicCertificateRecord.objects.filter(user_id=obj.pk)
        if education_record.filter(state=1).exists():
            return 1
        else:
            education = education_record.order_by('-created_time').first()
            if not education:
                return 3
            else:
                return education.state

    def get_user_group_type(self, obj):
        return 1 if Matchmaker.objects.filter(user_id=obj.pk, state=1).exists() else 0


class RecommUserSerializer(serializers.ModelSerializer):
    photos = serializers.SerializerMethodField()
    is_like = serializers.SerializerMethodField()  # 用户是否喜欢当前嘉宾
    car = serializers.SerializerMethodField()
    house = serializers.SerializerMethodField()
    gender = serializers.SerializerMethodField()
    circle_id = serializers.SerializerMethodField()
    circle_name = serializers.SerializerMethodField()
    is_education = serializers.SerializerMethodField()

    class Meta:
        model = Recommend
        fields = (
            "recomm_user_id", "photos", "career", "age", "height", "gender", "place_of_residence", "education",
            "annual_salary", "car", "house", "is_like", "circle_id", "circle_name", "is_education")

    def get_photos(self, obj):
        if obj.photos:
            return obj.photos.split(',')

    def get_car(self, obj):
        return '有车' if obj.car > 0 else '没车'

    def get_house(self, obj):
        # return '有房' if obj.house > 0 else '没房'
        return constants.HOUSE_STATUS[obj.house]

    def get_is_like(self, obj):
        """
        判断用户是否喜欢当前用户
        """
        if Like.objects.filter(from_user_id=obj.user_id, to_user_id=obj.recomm_user_id, is_like=True).exists():
            return True
        return False

    def get_gender(self, obj):
        return '' if obj.gender == 1 else ''

    def get_circle_id(self, obj):
        circle = utils.get_most_expensive_circle_belong(obj.recomm_user_id)
        if circle:
            return circle.pk
        else:
            return -1

    def get_circle_name(self, obj):
        circle = utils.get_most_expensive_circle_belong(obj.recomm_user_id)
        if circle:
            return circle.circle_name
        else:
            return ''

    def get_is_education(self, obj):
        return AcademicCertificateRecord.objects.filter(user_id=obj.recomm_user_id, state=1).exists()


class CardSerializer(serializers.ModelSerializer):
    info = serializers.SerializerMethodField()
    my_circle = serializers.SerializerMethodField()
    photos = serializers.SerializerMethodField()
    is_like = serializers.SerializerMethodField()
    age = serializers.SerializerMethodField()
    is_real = serializers.SerializerMethodField()
    fake_uid = serializers.SerializerMethodField()  # 虚拟用户ID
    is_education = serializers.SerializerMethodField()  # 是否学历认证

    class Meta:
        model = CircleUser
        fields = (
            'photos', 'career', 'gender', 'user_id', 'place_of_residence', 'info', 'my_circle', 'child_introduction',
            'hobbies', 'emotional_view', 'spouse_description', 'is_like', 'age', 'education', 'is_real', 'fake_uid',
            'is_education')

    def get_info(self, obj):
        res = []
        marriage_choice = constants.MARITAL_STATUS
        if obj.marriage:
            res.append(marriage_choice[obj.marriage])

        age = obj.age[0:4]
        try:
            age = int(age)
        except:
            logger.info("{} 错误".format(obj.age))
            age = 0
        if age > 0:
            res.append('{}岁'.format(datetime.datetime.now().year - age))
        if obj.height > 0:
            res.append('{}cm'.format(obj.height))
        if obj.monthly_salary:
            res.append('月薪:{}'.format(obj.monthly_salary))
        if obj.car:
            res.append(obj.car)
        if obj.house:
            res.append(obj.house)
        if obj.career:
            res.append(obj.career)
        if obj.place_of_residence:
            res.append(obj.place_of_residence)
        return res

    def get_my_circle(self, obj):
        return Circle.objects.filter(C2Us__user_id=obj.pk).values('id', 'circle_name')

    def get_photos(self, obj):
        return obj.photos.split(',')

    def get_is_like(self, obj):
        """
        判断用户是否喜欢当前用户
        """
        host_id = self.context['request'].user.user_id
        if Like.objects.filter(from_user_id=host_id, to_user_id=obj.user_id, is_like=True).exists():
            return True
        return False

    def get_age(self, obj):
        return obj.age[0:4]

    def get_is_real(self, obj):
        # return all([obj.real_name, obj.id_card])
        return obj.user_status == 0 or RealUserInformation.objects.filter(user_id=obj.pk).exists()

    def get_fake_uid(self, obj):
        return utils.encrypt_uid(obj.pk)

    def get_is_education(self, obj):
        return AcademicCertificateRecord.objects.filter(user_id=obj.pk, state=1).exists()


class PurchaseSerializer(serializers.ModelSerializer):
    slogan = serializers.SerializerMethodField()
    attraction = serializers.SerializerMethodField()
    discount = serializers.SerializerMethodField()  # 折扣

    class Meta:
        model = Circle
        fields = (
            'id', 'circle_name', 'slogan', 'single_buy_by_android', 'attraction', 'discount')

    def get_slogan(self, obj):
        """
        圈子介绍语,口号,标签信息
        """
        ikey = "circle_{}".format(obj.id)
        circle_config = Config.objects.filter(itype='group_advertising', ikey=ikey, ienable=1).order_by('-id').values(
            "ival").first()
        if not circle_config:
            logger.info('圈子 {} 缺少标签,介绍语等信息')
            return 32
        else:
            try:
                return json.loads(circle_config['ival'])['slogan']
            except:
                logger.info("{} 圈子标签配置信息json解析错误".format(obj.id))
                return 32

    def get_discount(self, obj):
        user = self.context['request'].user
        if obj.single_buy_by_android >= user.total_money:
            return user.total_money
        else:
            return obj.single_buy_by_android

    def get_intro(self, obj):
        ikey = "circle_%d" % obj.id
        circle_config = Config.objects.filter(itype='group_advertising', ikey=ikey, ienable=1).order_by('-id').first()

        if circle_config:
            try:
                return json.loads(circle_config.ival)['intro']
            except:
                logger.info('{} 圈子解析配置出错')
                return ''
        else:
            logger.info('{} 圈子缺少相关标签配置'.format(obj.id))
            return ''

    def get_attraction(self, obj):
        ikey = "circle_%d" % obj.id
        circle_config = Config.objects.filter(itype='group_advertising', ikey=ikey, ienable=1).order_by('-id').first()

        if circle_config:
            try:
                return json.loads(circle_config.ival)['attraction']
            except:
                logger.info('{} 圈子解析配置出错')
                return ''
        else:
            logger.info('{} 圈子缺少相关标签配置'.format(obj.id))
            return ''


class CutKnifeSerializer(serializers.ModelSerializer):
    class Meta:
        model = CutKnife
        fields = ('id', 'expire_time')


class GzhCirclesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Circle
        fields = (
            "id", "circle_name", "circle_description", "member_number", "heat", "dynamic_number",
            "single_buy_by_android",)


class CrowdorderingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Crowdordering
        fields = (
            "expire_time", "is_participate", "is_source", "group_id", "group_type", "is_finish",
            "gap_number", "avatar", "join_number", "circle_id", "circle_name", "circle_description", "short_desc",
            "created_time", "remind", "link_path", "is_join_circle_other_group")

    expire_time = serializers.SerializerMethodField()
    is_participate = serializers.SerializerMethodField()
    # is_join = serializers.SerializerMethodField()
    is_source = serializers.SerializerMethodField()
    is_finish = serializers.SerializerMethodField()
    gap_number = serializers.SerializerMethodField()
    avatar = serializers.SerializerMethodField()
    join_number = serializers.SerializerMethodField()
    circle_name = serializers.SerializerMethodField()
    circle_description = serializers.SerializerMethodField()
    short_desc = serializers.SerializerMethodField()
    remind = serializers.SerializerMethodField()
    link_path = serializers.SerializerMethodField()
    is_join_circle_other_group = serializers.SerializerMethodField()

    def get_expire_time(self, obj):
        self._obj = obj
        self._user = self.context['request'].user
        return obj.over_time

    @cached_property
    def cached_get_is_participate(self):
        return (self._obj.sponsor_user_id == self._user.pk) or Order.objects.filter(user_id=self._user.pk, state=1,
                                                                                    group_buy_id=self._obj.group_id).exists()

    def get_is_participate(self, obj):
        return self.cached_get_is_participate

    def get_is_source(self, obj):
        """
        是否是拼单发起者
        """
        return self._user.pk == self._obj.sponsor_user_id

    @cached_property
    def cached_get_is_finish(self):
        # 当前对改拼单是否完成
        return utils.is_user_group_success(self._user, self._obj)

    def get_is_finish(self, obj):
        """
        拼单是否完成
        """
        return self.cached_get_is_finish

    @cached_property
    def cached_get_gap_number(self):
        # 返回问号头像的个数
        if self.cached_get_is_finish:
            return 0
        elif self._obj.group_type == 0:
            return utils.get_group_gap_number(self._obj) - (self.cached_get_is_participate and (
                    self._user.pk != self._obj.sponsor_user_id))
        else:
            return max(0, utils.get_group_gap_number(self._obj) - self.cached_real_join_number)

    def get_gap_number(self, obj):
        return self.cached_get_gap_number

    @cached_property
    def cached_get_avatar(self):
        return utils.get_group_show_avatar(self._user, self._obj)

    def get_avatar(self, obj):
        """
        返回需要展示的头像 ( 加上问号头像 )
        """
        return self.cached_get_avatar + [constants.QUESTION_MARK_AVATAR] * self.cached_get_gap_number

    @cached_property
    def cached_real_join_number(self):
        # 获取拼单真实参与用户
        return len(utils.get_group_join_user(self._obj)) + self._obj.group_type

    def get_join_number(self, obj):
        # 用户前端显示的参与用户数 (与头像数保持一致)
        return len(self.cached_get_avatar)

    @cached_property
    def cached_get_circle(self):
        return Circle.objects.get(pk=self._obj.circle_id)

    def get_circle_name(self, obj):
        return self.cached_get_circle.circle_name

    def get_circle_description(self, obj):
        return self.cached_get_circle.circle_description

    def get_short_desc(self, obj):
        return self.cached_get_circle.short_desc

    def get_remind(self, obj):
        return "如果超过拼单时间未成功拼单,已支付拼单金额将退还至原支付账户"

    def get_link_path(self, obj):
        group_config = utils.get_circle_group_config(obj.circle_id, is_force=True)
        if group_config:
            return group_config['link_path']
        else:
            return ''

    def get_is_join_circle_other_group(self, obj):
        """
        用户是否参与该圈子的拼单 或 已经进圈
        :param obj:
        :return:
        """
        if Circle2CircleUser.objects.filter(user_id=self._user.pk, circle_id=obj.circle_id) or Order.objects.filter(
                user_id=self._user.pk, circle_id=obj.circle_id, state=1, is_group=True).exists():
            return True
        else:
            return False


class IdentifyingCodeSerizliser(serializers.ModelSerializer):
    class Meta:
        model = IdentifyingCode
        fields = (
            'id',
            "user_id",
            'phone',
            'expired',
        )

    def create(self, validated_data):
        # logger.info('[create] validated_data=%s', validated_data)
        phone = validated_data['phone']

        r_code, r_expired = validated_data['code'], validated_data['expired']

        # 添加验证码白名单
        if phone in constants.PHONE_CODE_WHITELIST or settings.IS_DEV:
            r_code = '000000'
            r_expired = datetime.datetime(2099, 1, 1)

        record = IdentifyingCode.objects.create(user_id=self.context["request"].user.user_id, phone=phone,
                                                identifying_code=r_code,
                                                expired=r_expired)

        try:
            ts.send_message_async.delay(record.phone, record.identifying_code)
        except Exception as e:
            logger.info('[send_message_async] %s:%s %s', (phone, r_code, e))
        return record


class MatchmakerAreaConfigSerializer(serializers.ModelSerializer):
    class Meta:
        model = MatchmakerAreaConfig
        fields = (
            "id",
            "area",
            "money",
            "detail"
        )

    detail = serializers.SerializerMethodField()

    def get_detail(self, obj):
        try:
            detail = json.loads(obj.detail)
        except Exception:
            detail = {}
        return detail


class MatchmakerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Matchmaker
        fields = (
            "user_id",
            "phone",
            "avatar",
            "place_of_residence",
            "crowdordering_royalty",
            "today_crowdordering_royalty",
            "inferior_num",
            "today_inferior_num"
        )

    crowdordering_royalty = serializers.SerializerMethodField()
    today_crowdordering_royalty = serializers.SerializerMethodField()
    inferior_num = serializers.SerializerMethodField()
    today_inferior_num = serializers.SerializerMethodField()

    def get_crowdordering_royalty(self, obj):
        money = IncomeAndExpenditure.objects.filter(user_id=obj.user_id, state=1, source=1).aggregate(
            total=Sum("operate_money"))
        return money["total"] if money and money["total"] else 0

    def get_today_crowdordering_royalty(self, obj):
        money = IncomeAndExpenditure.objects.filter(user_id=obj.user_id, state=1, source=1,
                                                    created_time__gte=datetime.date.today()).aggregate(
            total=Sum("operate_money"))
        return money["total"] if money and money["total"] else 0

    def get_inferior_num(self, obj):
        return IncomeAndExpenditure.objects.filter(user_id=obj.user_id, state=1, source=2).count()

    def get_today_inferior_num(self, obj):
        return IncomeAndExpenditure.objects.filter(user_id=obj.user_id, state=1, source=2,
                                                   created_time__gte=datetime.date.today()).count()

    @property
    def data(self):
        ret = super(MatchmakerSerializer, self).data
        result = {"errcode": 0, "detail": "success", "data": ret}
        return result
原文地址:https://www.cnblogs.com/tangda/p/12419728.html