当前代码
我有两个模型(发布和查看),如下所示。视图是针对哪个用户查看了哪个帖子。
发布模型:
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来处理请求。您可以问我是否需要其他信息来回答我的问题。任何帮助将不胜感激。
答案 0 :(得分:1)
您可以使用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)
在您看来,可以通过将当前的PostSerializer
对象提供给序列化程序的上下文,来使用新创建的request
。
此后,您可以受益于SerializerMethodField
来显示viewed_by_user
属性。
如果还有其他问题,请确保在下面发表评论。 :)
答案 1 :(得分:1)
您可以使用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)