python - DRF:正确使用序列化器和视图集的理论方法
问题描述
我喜欢 Python 和 Django,过去几周我一直在学习 Django REST 框架,因为在 2020 年的今天,没有人可以逃到 REST。在我的爱好项目中(这是一个 Python 论坛,可笑地称为 Pyrty,因为它是一个 Python派对),我决定为comments
应用程序制作一个 CRUD。我做到了(通过更新除外),但我不明白将代码放入序列化程序和/或视图集中有什么区别。
My create
andlist
在序列化器中,而delete
在 ViewSet 中。所有这些都按预期工作,但我不想编写脏代码,我希望了解将某些东西放在一个或另一个部分的重点和区别。
评论.models.py:
class Comment(PyrtyModel): # the inheritance class just adds creation and modification dates, and sorting stuff
user = models.ForeignKey('users.User', on_delete=models.CASCADE, null=False)
post = models.ForeignKey('posts.Post', on_delete=models.CASCADE, null=False)
content = models.TextField(max_length=1000, null=False, blank=False)
positive_votes = models.ManyToManyField('users.User', related_name='c_positive_vote_set')
negative_votes = models.ManyToManyField('users.User', related_name='c_negative_vote_set')
score = 0
def __init__(self, *args, **kwargs):
# init with the score (positive votes - negative votes) if the comment is persisted
super(Comment, self).__init__(*args, **kwargs)
if self.id is not None:
self.score = (
self.positive_votes.all().count() -
self.negative_votes.all().count()
)
def __str__(self):
"""Return the comment str."""
return "'{}'".format(self.content)
class Meta(PyrtyModel.Meta):
ordering = ['created', 'modified']
评论.serializers.py:
class CommentSerializer(serializers.ModelSerializer):
"""Comment model serializer."""
user = serializers.PrimaryKeyRelatedField(read_only=True)
class Meta:
model = Comment
fields = '__all__'
def create(self, validated_data):
"""Create a new comment in some post, by request.user."""
validated_data['user'] = self.context['request'].user
return super().create(validated_data)
def list(self, request):
"""List all the comments from some post."""
if 'post' not in request.query_params:
raise ValidationError('Post id must be provided.')
q = self.queryset.filter(post=request.query_params['post'])
serializer = CommentSerializer(q, many=True)
return Response(serializer.data)
评论.views.py:
class CommentViewSet(viewsets.ModelViewSet):
serializer_class = CommentSerializer
queryset = Comment.objects.all()
def get_permissions(self):
permissions = []
if self.action == 'create' or self.action == 'destroy':
permissions.append(IsAuthenticated)
return [p() for p in permissions]
def get_object(self):
"""Return comment by primary key."""
return get_object_or_404(Comment, id=self.kwargs['pk'])
def destroy(self, request, *args, **kwargs):
"""Delete a comment created by request.user from a post."""
instance = self.get_object()
if instance.user != request.user:
raise ValidationError('Comment does not belong to the authenticated user.')
self.perform_destroy(instance)
run_reputation_update(request.user)
return Response(status=status.HTTP_204_NO_CONTENT)
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
我应该在哪里以及何时将代码放在其中的一部分?
解决方案
序列化器用于验证请求数据(传入参数)并格式化(序列化)数据以作为响应返回。
此外,序列化程序具有类似的方法,create
您可以在其中定义应如何保存已验证数据的逻辑。这对于 ModelSerilizers 来说尤其方便。update
save
所有其他逻辑都应在视图/视图集中定义。
我很确定你list
在你的方法CommentSerializer
没有做任何事情。因为序列化程序没有list
方法,你在那里定义了它,但它从未使用过。ModelViewSet
另一方面有list
方法,我很确定这是您获取评论列表时使用的list
方法,而不是序列化程序中的方法。
推荐阅读
- delphi - 使用 extCreatePen 的虚线不在 Delphi 中打印
- django - 从 Listview 中的其他模型获取字段的总和
- ios - 当没有为位置服务授予权限时,MKUserTrackingButton 会变成一个微调器
- php - 这个 php 操作符是做什么的?
- spring - 如何使用 Spring MVC 动态绑定表单元素
- google-cloud-platform - 在 Google Cloud VM 上找不到文件
- angular - RXJS groupBy Observable
- c# - Windows 7 进程 ID 循环引用
- php - 使用 Laravel 5.5 启用 PHP 错误日志记录
- r - 根据调查类型的ggmap颜色