【问题标题】:Django rest framework merging two serializers data based on following requirementDjango rest框架根据以下要求合并两个序列化器数据
【发布时间】:2021-05-20 14:40:59
【问题描述】:

我有两个模型,一个是 Video,其中包含所有用户上传的详细信息,另一个模型是 LikedVideo,其中包含用户喜欢的视频的详细信息。

视频模型

class Video(models.Model):
    """
    All videos available for the users
    """
  
    video = models.FileField(blank=True, default='')
    user = models.ForeignKey(User, related_name='user_videos', related_query_name='person', on_delete=models.SET_NULL, null=True)
    category = models.ForeignKey(VideoCategory, related_name='video_category', on_delete=models.SET_NULL, null=True)
    channel = models.ForeignKey(Channel, related_name='video_channel', on_delete=models.SET_NULL, null=True)
    uploaded_at = models.DateTimeField(auto_now_add=True)
    deleted_at = models.DateTimeField(null=True)
    active = models.BooleanField(default=1)
    description = models.TextField(null=True)
    short_description = models.CharField(max_length=150, null=True)

    def __str__(self):
        return f"{self.user.username}_{self.category.video_type}_{self.channel.channel_name}"

LikedVideo 模型

class LikedVideo(models.Model):
    """
    Contains all the liked videos by user
    """
    video = models.ForeignKey(Video, related_name='video_liked', on_delete=models.SET_NULL, null=True)
    user = models.ForeignKey(User, related_name='user_liked', on_delete=models.SET_NULL, null=True)
    liked = models.BooleanField(default=0)
    
    def __str__(self):
        return f"{self.user.username}"

视频序列化器

class VideoSerializer(ModelSerializer):

    uploaded_at = serializers.ReadOnlyField()

    class Meta:
        model = Video
        fields = ["id", "video", "category", "uploaded_at", "channel", "description", "short_description"]

    def to_representation(self, instance):
        rep = super(VideoSerializer, self).to_representation(instance)
        rep['category'] = instance.category.video_type
        rep['channel'] = instance.channel.channel_name
        return rep

    def validate_channel(self, value):
        print(self.context['request'].user)
        if Channel.objects.filter(user=self.context['request'].user, channel_name=value).exists():
            return value
        raise serializers.ValidationError(_(f"Channel {value} does not belongs you. Please, enter a channel belongs to you"))

LikedVideoSerializer

class LikedVideoSerializer(serializers.ModelSerializer):

    class Meta:
        model = LikedVideo
        fields = ["id", "video", "liked", "user"]

VideoListAPIView

class VideoListAPIView(generics.ListAPIView):
    queryset = Video.objects.all()
    serializer_class = VideoSerializer

    def list(self, request, format=None):
        queryset = Video.objects.all()
        video_serializer = VideoSerializer(queryset, many=True)
        liked_videos = LikedVideo.objects.filter(user=request.user)
        liked_video_serializer = LikedVideoSerializer(liked_videos, many=True)

        print(video_serializer.data, "\n", liked_video_serializer.data)

我需要一个包含所有视频详细信息的序列化程序,并将登录用户喜欢的视频合并到视频详细信息中

  1. 需要构建一个返回所有视频详细信息的序列化程序。
  2. 在视频详情中需要为登录用户添加一个额外的字段video_liked,即TrueFalse。 (喜欢的视频详细信息应仅适用于登录用户并合并到全部视频详细信息)

对于我的逻辑,我得到如下输出

Video Details

[OrderedDict([('id', 8), ('video', '/media/dd_sNq8cWy.mp4'), ('category', 'Entertainment'), ('uploaded_at', datetime.datetime(2021, 5, 15, 8, 12, 52, 592654, tzinfo=<UTC>)), ('channel', 'lovelymouniii'), ('description', 'en'), ('short_description', 'msmms')]), OrderedDict([('id', 11), ('video', '/media/dd_9UP5kVD.mp4'), ('category', 'Entertainment'), ('uploaded_at', datetime.datetime(2021, 5, 16, 13, 17, 36, 328416, tzinfo=<UTC>)), ('channel', 'janaTrolling'), ('description', 'hhh'), ('short_description', 'hhh')]), OrderedDict([('id', 12), ('video', '/media/dd_wFe6tcb.mp4'), ('category', 'others'), ('uploaded_at', datetime.datetime(2021, 5, 16, 13, 38, 49, 917408, tzinfo=<UTC>)), ('channel', 'teluguGamer'), ('description', 'dsds'), ('short_description', 'dsdsdsd')]), OrderedDict([('id', 13), ('video', '/media/dd_JtxMzeD.mp4'), ('category', 'others'), ('uploaded_at', datetime.datetime(2021, 5, 16, 13, 50, 26, 645462, tzinfo=<UTC>)), ('channel', 'janaTrolling'), ('description', 'sdsd'), ('short_description', 'sdsds')])]
and liked videos as separate list

显示所有视频并将登录用户的喜欢视频与视频详细信息合并。

【问题讨论】:

    标签: python-3.x django django-models django-rest-framework django-views


    【解决方案1】:

    最简单的方法应该是为您的视频模型添加一个属性方法:

    @property
    def is_liked(self):
        user = User.objects.get(id=request.user.id)
        liked = LikedVideo.objects.filter(video=self, user=user).values_list('liked')
        return liked
    

    然后直接在你的 VideoSerializer 中引用它fields

    【讨论】:

    • 如何在is_liked()中访问请求对象?
    • 感谢@NoneType 它在查询用户模型中的工作但略有变化,将 user = User.objects.get(id=request.user.id) 更改为 user = User.objects.get(id=self.user.id)
    猜你喜欢
    • 2021-11-02
    • 2016-03-23
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 2020-03-22
    • 2015-10-29
    相关资源
    最近更新 更多