序列化第三张表的数据

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

猜你喜欢

转载自www.cnblogs.com/tangda/p/12419728.html
今日推荐