123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- from rest_framework import serializers
- from .models import Group, Membership, Post
- from accounts.models import CustomUser, InterestTag
- from accounts.serializers import InterestTagSerializer as AccountsInterestTagSerializer
- # --- Minimal Serializers for nested representations ---
- class MinimalUserSerializer(serializers.ModelSerializer):
- avatar_url = serializers.SerializerMethodField()
- class Meta:
- model = CustomUser
- fields = ('id', 'nickname', 'avatar_url')
- def get_avatar_url(self, obj):
- request = self.context.get('request')
- if obj.avatar and hasattr(obj.avatar, 'url'):
- if request is not None:
- return request.build_absolute_uri(obj.avatar.url)
- return obj.avatar.url
- return None
- class MinimalGroupSerializer(serializers.ModelSerializer):
- class Meta:
- model = Group
- fields = ('id', 'name')
- # --- Main Serializers ---
- class GroupSerializer(serializers.ModelSerializer):
- creator = MinimalUserSerializer(read_only=True)
- members_count = serializers.IntegerField(source='members.count', read_only=True)
-
- tags = serializers.PrimaryKeyRelatedField(
- queryset=InterestTag.objects.all(),
- many=True,
- required=False,
- allow_empty=True
- )
- tags_details = AccountsInterestTagSerializer(source='tags', many=True, read_only=True)
- cover_image = serializers.ImageField(max_length=None, use_url=True, required=False, allow_null=True)
- cover_image_url = serializers.SerializerMethodField(read_only=True)
- class Meta:
- model = Group
- fields = (
- 'id', 'name', 'description',
- 'cover_image', 'cover_image_url',
- 'creator', 'members_count',
- 'tags', 'tags_details',
- 'created_at', 'updated_at'
- )
- read_only_fields = ('id', 'created_at', 'updated_at', 'creator', 'members_count', 'tags_details', 'cover_image_url')
- def get_cover_image_url(self, obj):
- request = self.context.get('request')
- if obj.cover_image and hasattr(obj.cover_image, 'url'):
- if request is not None:
- return request.build_absolute_uri(obj.cover_image.url)
- return obj.cover_image.url
- return None
- def create(self, validated_data):
- tags_data = validated_data.pop('tags', None)
- group = super().create(validated_data)
- if tags_data is not None:
- group.tags.set(tags_data)
- return group
- def update(self, instance, validated_data):
- tags_data = validated_data.pop('tags', None)
- instance = super().update(instance, validated_data)
- if tags_data is not None:
- instance.tags.set(tags_data)
- return instance
- class MembershipSerializer(serializers.ModelSerializer):
- user = MinimalUserSerializer(read_only=True)
- group_id = serializers.IntegerField(source='group.id', read_only=True)
- group_name = serializers.CharField(source='group.name', read_only=True)
- class Meta:
- model = Membership
- fields = ('id', 'user', 'group_id', 'group_name', 'date_joined')
- read_only_fields = ('id', 'user', 'group_id', 'group_name', 'date_joined')
- class PostSerializer(serializers.ModelSerializer): # 经过再次修正和简化的 PostSerializer
- author = MinimalUserSerializer(read_only=True) # 作者信息只读,在GET时显示
- group = MinimalGroupSerializer(read_only=True) # 小组信息只读,在GET时显示
- class Meta:
- model = Post
- fields = (
- 'id',
- 'group', # 在GET时显示小组信息 (只读)
- 'author', # 在GET时显示作者信息 (只读)
- 'title',
- 'content',
- # 'image', # 如果模型中有 image 字段,可以在这里添加用于上传
- # 'image_url', # 如果模型中有 image 字段,可以添加 get_image_url 方法
- 'created_at',
- 'updated_at',
- )
- # author 和 group 将在视图的 serializer.save() 中设置,所以它们对客户端来说是只读的
- # title 和 content 是客户端在创建帖子时可以发送的
- read_only_fields = ('id', 'author', 'group', 'created_at', 'updated_at')
-
- # create 方法不需要特别修改,因为 author 和 group 会在视图的 save() 中传入
- # def create(self, validated_data):
- # # validated_data 只包含客户端发送的 title, content
- # # author 和 group 是通过 serializer.save(author=request.user, group=group) 传入的
- # # ModelSerializer的默认create会将这些额外参数设置到模型实例上
- # return super().create(validated_data)
- # 实际上,DRF的ModelSerializer在调用save时传递的额外关键字参数,
- # 会在模型实例被创建(通过调用模型的objects.create或类似方法)之前,
- # 被添加到传递给模型构造函数的关键字参数中。
- # 所以,PostSerializer 的 create 方法可以保持默认,或者明确地像下面这样处理(如果需要更细致控制)
- # def create(self, validated_data):
- # # author 和 group 是从 serializer.save(author=..., group=...) 传递过来的
- # # 它们现在应该在 validated_data 中,或者需要从 context 中获取
- # # 更准确地说,它们会作为额外参数传递给模型的create方法
- # # 保持默认的 super().create() 即可,只要视图的save()调用正确
- # return super().create(validated_data)
- # 我们让 PostSerializer 的 create 方法保持默认,依赖视图的 serializer.save(author=..., group=...)
|