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