class PostListSerializer(ModelSerializer): """ Post列表 """ url = HyperlinkedIdentityField(view_name="post:detail") user = HyperlinkedRelatedField(view_name="userprofile:detail", read_only=True) created = TimestampField(read_only=True) updated = TimestampField(read_only=True) user_name = SerializerMethodField() point = PointDetailSerializer(many=True, read_only=True) class Meta: model = Post fields = [ 'url', 'id', 'user', 'user_name', 'title', 'location', 'views', 'created', 'updated', 'point', ] def get_user_name(self, obj): return obj.user.username
class UserListSerializer(ModelSerializer): """ User用户列表 含有拓展的Profile用户数据列表 """ url = HyperlinkedIdentityField(view_name="userprofile:detail") profile = SerializerMethodField() date_joined = TimestampField() last_login = TimestampField() class Meta: model = User fields = [ 'url', 'id', 'username', 'email', 'last_login', 'date_joined', 'profile', ] # 获取Profile表 def get_profile(self, obj): c_qs = Profile.objects.get(user=obj.id) profile = ProfileListSerializer(c_qs).data return profile
class CommentListSerializer(ModelSerializer): """ 评论列表 """ url = HyperlinkedIdentityField(view_name='comment:detail', ) post = HyperlinkedRelatedField( view_name='post:detail', read_only=True, ) user = HyperlinkedRelatedField( view_name='userprofile:detail', read_only=True, ) post_title = SerializerMethodField() user_name = SerializerMethodField() created = TimestampField() class Meta: model = Comment fields = [ 'url', 'post', 'user', 'post_title', 'user_name', 'content', 'created', ] def get_post_title(self, instance): return instance.post.title def get_user_name(self, instance): return instance.user.username
class Scrobble(m.Model): user = m.ForeignKey(User, related_name='scrobbles') track = m.ForeignKey(Track, related_name='scrobbles') timestamp = TimestampField() class Meta: app_label = 'lastfm' def __unicode__(self): return '%s played %s' % (unicode(self.user), unicode(self.track))
class Favorite(m.Model): user = m.ForeignKey(User, related_name='favorites') track = m.ForeignKey(Track, related_name='favorites') timestamp = TimestampField() objects = m.Manager() parser = FavoriteManager() class Meta: app_label = 'soundcloud' def __unicode__(self): return '%s favorites %s' % (unicode(self.user), unicode(self.track))
class PlayCount(QuerySetModel): user = m.ForeignKey(User, related_name='playcounts') track = m.ForeignKey(Track, related_name='playcounts') timestamp = TimestampField() count = m.IntegerField() class Meta: app_label = 'lastfm' def __unicode__(self): return '%sx %s by %s' % (self.count, unicode( self.track), unicode(self.user)) class QuerySet(m.query.QuerySet): def sum(self): return self.aggregate(m.Sum('count'))['count__sum'] or 0
class ProfileListSerializer(ModelSerializer): """ 序列化Profile列表,与User表一对一关联 """ birthday = TimestampField() class Meta: model = Profile fields = [ 'phone', 'gender', 'birthday', 'address', 'avatar', 'bio', 'tags', 'level', ]
class Playback(m.Model): user = m.ForeignKey(User, related_name='playbacks') track = m.ForeignKey(Track, related_name='playbacks') timestamp = TimestampField() count = m.IntegerField() objects = QuerySetManager() parser = PlaybackManager() class Meta: app_label = 'soundcloud' def __unicode__(self): return '%sx %s by %s' % (self.count, unicode(self.track), unicode(self.user)) class QuerySet(m.query.QuerySet): def sum(self): return self.aggregate(m.Sum('count'))['count__sum'] or 0
class CommentDetailSerializer(ModelSerializer): """ 删除、更新、查看Comment json [PUT]: { "content": str } """ created = TimestampField(read_only=True) post = HyperlinkedRelatedField( view_name='post:detail', read_only=True, ) user = HyperlinkedRelatedField( view_name='userprofile:detail', read_only=True, ) post_title = SerializerMethodField() user_name = SerializerMethodField() class Meta: model = Comment fields = [ 'id', 'post', 'user', 'post_title', 'user_name', 'content', 'created', ] read_only_fields = [ 'user', 'post', ] def get_post_title(self, instance): return instance.post.title def get_user_name(self, instance): return instance.user.username
class CommentPostSerializer(ModelSerializer): """ 在Post中展示的Comments """ url = HyperlinkedIdentityField(view_name='comment:detail') created = TimestampField(read_only=True) user_name = SerializerMethodField() class Meta: model = Comment fields = [ 'url', 'user_name', 'content', 'created', ] def get_user_name(self, instance): return instance.user.username
class PointListSerializer(ModelSerializer): """ Point列表 """ url = HyperlinkedIdentityField(view_name="point:detail") travel_date_time = TimestampField() class Meta: model = Point fields = [ 'url', 'post', 'longitude', 'latitude', 'travel_date_time', 'name', 'expend', 'content', ]
class PointDetailSerializer(ModelSerializer): """ 查看、更新、删除Point """ travel_date_time = TimestampField() class Meta: model = Point fields = [ 'id', 'post', 'longitude', 'latitude', 'travel_date_time', 'name', 'expend', 'content', ] read_only_fields = [ 'post', ]
class PointCreateSerializer(ModelSerializer): """ 序列化新的Point表 """ travel_date_time = TimestampField() class Meta: model = Point fields = [ 'post', 'longitude', 'latitude', 'travel_date_time', 'name', 'expend', 'content', ] # 创建新的模型 def create(self, validated_data): point = Point.objects.create(**validated_data) return point
class User(CustomUser): USERNAME_FIELD = 'id' """Twitter user infomation""" # Active fields id = m.BigIntegerField(primary_key=True) id_str = NullTextField() name = NullTextField() screen_name = NullTextField() description = NullTextField() profile_image_url = NullTextField() # Timestamps date_acquired = TimestampField() last_update = m.DateTimeField(auto_now=True) # Future fields """ protected = m.BooleanField(null=True) verified = m.BooleanField(null=True) created_at = m.DateTimeField(null=True) followers_count = m.PositiveIntegerField(null=True) favourites_count = m.PositiveIntegerField(null=True) statuses_count = m.PositiveIntegerField(null=True) url = m.URLField(verify_exists=False) location = m.CharField(max_length=30, blank=True) time_zone = m.CharField(max_length=50, blank=True) utc_offset = m.IntegerField(null=True) """ def __str__(self): return ((self.screen_name and '@%s' % self.screen_name) or self.name or unicode(self.id)) class Meta: app_label = 'twitter'
class ProfileDetailSerializer(ModelSerializer): """ Profile表的查看、更新 Profile表必须通过User表才能删除 并对数据验证 """ birthday = TimestampField(required=False) class Meta: model = Profile fields = [ 'phone', 'gender', 'birthday', 'address', 'avatar', 'bio', 'tags', 'level', ] read_only_fields = [ 'level', ] # 验证电话号码是否合法 def validate_phone(self, value): if len(value) != 11 or not value.isdigit(): raise ValidationError("请输入11位电话号码.") return value # 验证性别是否正确 def validate_gender(self, value): gender_list = ['男', '女'] if value not in gender_list: raise ValidationError("性别必须为'男'或'女'") return value
class UserDetailSerializer(ModelSerializer): """ User表的查看、更新、删除 """ date_joined = TimestampField(read_only=True) last_login = TimestampField(read_only=True) profile = ProfileDetailSerializer() post = PostUserSerializer(many=True, read_only=True) class Meta: model = User fields = [ 'id', 'username', 'password', 'email', 'last_login', 'date_joined', 'profile', 'post', ] read_only_fields = [ 'username', ] extra_kwargs = { 'password': {'write_only': True} } # 验证password是否合法 def validate_password(self, value): data = self.get_initial() password = data.get('password') if len(password) < 6: raise ValidationError("密码至少6位。") return value # email数据验证,不允许与已有的email相同 def validate_email(self, value): data = self.get_initial() email = data.get('email') user_qs = User.objects.exclude(email__isnull=True).exclude(email__exact='').filter(email=email) if user_qs.exists(): raise ValidationError("本邮箱已被注册。") return value def update(self, instance, validated_data): """ 更新User表、Profile表的数据 :param instance: 待更新的模型实例 :param validated_data: 用户提交的数据 :return: 模型实例 """ # 更新Profile数据 if 'profile' in validated_data: profile_data = validated_data.pop('profile') profile = Profile.objects.get(id=instance.id) profile.user = instance # 循环检查数据更新 for key, value in profile_data.items(): setattr(profile, key, value) profile.save() # 更新User数据 if 'email' in validated_data: instance.email = validated_data['email'] if 'password' in validated_data: instance.set_password(validated_data['password']) instance.save() return instance
class PostDetailSerializer(ModelSerializer): """ Post的查看、更新、删除 json格式如下: { "title": str, "content": str, ... point: { "create": [ { "latitude": num, "longitude": num, ... }, ... ], "delete": [ { "id": num, }, ... ] "update": [ { "id": num, "latitude": num, "longitude": num, ... }, ... ] } } """ user = HyperlinkedRelatedField(view_name="userprofile:detail", read_only=True) created = TimestampField(read_only=True) updated = TimestampField(read_only=True) user_name = SerializerMethodField() point = PointDetailSerializer(many=True, read_only=True) comment = CommentPostSerializer(many=True, read_only=True) class Meta: model = Post fields = [ 'id', 'user', 'user_name', 'title', 'views', 'location', 'created', 'updated', 'content', 'point', 'comment', ] read_only_fields = [ 'id', 'user', 'user_name', 'views', 'created', 'updated', ] def get_user_name(self, obj): return obj.user.username # 重写update方法 # 可以从这里更新相关的Point表了 def update(self, instance, validated_data): request = self.context.get("request") if request.data.get("point"): # print(request.data.get("point")) # 遍历point数组,对Point表进行更新、创建、删除 for method, point_objs in request.data.get("point").items(): if method == 'create': for point_obj in point_objs: point_obj['post'] = instance Point.objects.create(**point_obj) elif method == 'update': for point_obj in point_objs: point = Point.objects.get(id=point_obj['id']) del point_obj['id'] for key, value in point_obj.items(): setattr(point, key, value) point.save() elif method == 'delete': for point_obj in point_objs: point = Point.objects.get(id=point_obj['id']) point.delete() else: raise ValidationError("method必须为create/update/delete") # for p_dict in request.data.get("point"): # method = p_dict['method'] # del p_dict['method'] # # # 如果method元素为create,则创建一个新的Point # if method == "create": # p_dict['post'] = instance # Point.objects.create(**p_dict) # # # method为update,则更新现有的Point # elif method == 'update': # point_obj = Point.objects.get(id=p_dict['id']) # del p_dict['id'] # for key, value in p_dict.items(): # setattr(point_obj, key, value) # point_obj.save() # # # method为delete,则删除Point # elif method == 'delete': # point_obj = Point.objects.get(id=p_dict['id']) # point_obj.delete() # # else: # raise ValidationError("method必须为create/update/delete") # 更新Post内容 instance.title = validated_data.get('title', instance.title) instance.content = validated_data.get('content', instance.content) instance.location = validated_data.get('location', instance.location) instance.save() return instance