Django 使用来自其他模型的信息序列化对象



当前代码

我有两个模型(发布和查看(,如下所示。查看是哪个用户看到了哪个帖子。

帖子模型:

class Post(models.Model):
    creator = models.ForeignKey(User, on_delete = models.CASCADE)
    text = models.CharField(max_length = 255)
    timestamp = models.DateTimeField(default=now)
    def __str__(self):
        return str(self.pk)

查看模型:

class View(models.Model):
    viewer = models.ForeignKey(User, on_delete = models.CASCADE)
    post = models.ForeignKey(Post, on_delete = models.CASCADE)
    timestamp = models.DateTimeField(default=now)
    def __str__(self):
        return str(self.post.pk)
    class Meta:
        unique_together = ('post', 'viewer')

我的 views.py 目前如下所示:

@api_view(['GET'])
@login_required
def get_posts(request):
     posts = list(Post.objects.all())
     data = serialize('json', posts, use_natural_foreign_keys=True)
     return HttpResponse(data, content_type="application/json")

问题所在

现在,我希望能够序列化许多 Post 对象,并为每个对象添加一个属性,说明发出请求的用户 ( request.user ( 是否查看了 Post。

我希望收到的结果示例:

[
{
    "model": "posts.post",
    "pk": 1,
    "fields": {
        "creator": ...,
        "content": "This is a sample post",
        "timestamp": "2019-07-07T19:56:07.220Z",
        "viewed_by_user": true <--- I want this attribute
    }
},
{
    "model": "posts.post",
    "pk": 2,
    "fields": {
        "creator": ...,
        "content": "This is another sample post",
        "timestamp": "2019-07-10T13:04:19.220Z",
        "viewed_by_user": false <--- I want this attribute
    }
}
]

我可以用 django 序列化程序来实现这一点吗?我应该以不同的方式构建我的模型吗?

我正在使用django-rest-framework来处理请求。您可以问我是否需要任何其他信息来回答我的问题。任何帮助将不胜感激。

您可以使用

DRF 中的标准ModelSerializer

serializers.py

from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    viewed_by_user = serializers.SerializerMethodField()
    class Meta:
        model = Post
        fields = ('pk', 'creator', 'text', 'timestamp', 'viewed_by_user')
    def get_viewed_by_user(self, instance):
        user = self.context['request']. user
        return instance.view_set.filter(viewer=user).exists()

然后

views.py

from rest_framework.response import Response
...
from .serializers import PostSerializer

@api_view(['GET'])
@login_required
def get_posts(request):
     posts = Post.objects.all()
     serializer = PostSerializer(posts, many=True, context={'request': request})
     return Response(serializer.data)

在视图中,可以通过向序列化程序提供当前request对象作为上下文来使用新创建的PostSerializer

之后,您可以从SerializerMethodField中受益,以显示viewed_by_user属性。

如果您有任何其他问题,请务必在下面发表评论。 :)

您可以使用DRF来实现此目的,并且不需要单独的模型来计算查看特定帖子的用户

models.py

class Post(models.Model):
    creator = models.ForeignKey(User, on_delete = models.CASCADE)
    text = models.CharField(max_length = 255)
    timestamp = models.DateTimeField(default=now)
    viewed_by = models.ManyToManyField(User, null=True, blank=True, related_name='viewer')
    def __str__(self):
        return str(self.pk)

serializers.py

使用serializerMethord检查用户是否查看了特定帖子

from rest_framework import serializers
from .models import Post

    class PostSerializers(serializers.ModelSerializer):
        viewed = serializers.SerializerMethodField()
        class Meta:
            model = Post
            fields = [
                'viewed',
                'text',
                'timestamp'
            ]
        def get_viewed(self, obj):
            print(self.context['request'].user, obj.viewed_by)
            if self.context['request'].user in obj.viewed_by.all():
                return True
            return False

然后在views.py

from rest_framework.generics import ListAPIView
from .models import Post
from .serializers import PostSerializers
    class PostListView(ListAPIView):
        queryset = Post.objects.all()
        serializer_class = PostSerializers

您可以按以下方式计算每个视图

class PostDetailView(RetrieveAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializers
    def get(self, request, *args, **kwargs):
        data = self.get_object()
        data.viewed_by.add(request.user)
        data.save()
        return self.retrieve(request, *args, **kwargs)

最新更新