我在重新制作一个社交媒体网站,作为Django和rest框架的修订版,我不想使用Django默认的线性id计数,也不喜欢uuid库的id有多长,所以我使用了shortuuid库.我在帖子和 comments 中使用它们只是为了保持帖子和 comments 数量的匿名性.在posts方面,所有内容都适用于CRUD(据我所知,这应该证明问题不是来自shortuuid库),尽管在注释中,Create REQUIRE工作得很好,但Update Destroy没有.下面是我们正在使用的代码:

从模型开始,了解我们正在处理的数据类型(models.py):

from shortuuid.django_fields import ShortUUIDField

... # posts likes etc


class Comment(models.Model):
    id = ShortUUIDField(primary_key=True, length=8, max_length=10)
    user    = models.ForeignKey(User, on_delete=models.CASCADE)
    post    = models.ForeignKey(Post, on_delete=models.CASCADE)
    body    = models.TextField(max_length=350)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    active  = models.BooleanField(default=True)

    class Meta:
        ordering = ['created']

    def __str__(self):
        return f'on {self.post} by {self.user}'

    objects = models.Manager()

序列化程序.py:

class CommentSerializer(ModelSerializer):
    username = SerializerMethodField()

    def get_username(self, comment):
        return str(comment.user)

    class Meta:
        model = Comment
        fields = ['id', 'user', 'post', 'username', 'body', 'created', 'updated']
        read_only_fields = ['id', 'post', 'user', 'username']

现在使用路由(URL.py):

from django.urls import path
from .views import *


urlpatterns = [
    ...

    path('<str:pk>/comments/'       , Comments),
    path('<str:pk>/comments/create/', CreateComment),
    path('<str:pk>/comments/<str:cm>/', ModifyComment),
    # pk = post ID
    # cm = comment ID
]

意见.py:

class ModifyComment(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = CommentSerializer
    permission_classes = [permissions.AllowAny]

    def get_queryset(self):
        post = Post.objects.get(pk=self.kwargs['pk'])
        comment = Comment.objects.get(post=post, pk=self.kwargs['cm'])
        return comment


    def perform_update(self, serializer):
        print(Post.objects.all())
        post = Post.objects.get(pk=self.kwargs['pk'])
        comment = Comment.objects.filter(pk=self.kwargs['cm'], post=post)
        if self.request.user != comment.user:
            raise ValidationError('you can\'t edit another user\'s post')
        if comment.exists():
            serializer.save(user=self.request.user, comment=comment)
        else:
            raise ValidationError('the comment doesnt exist lol')

    def delete(self, request, *args, **kwargs):
        comment = Comment.objects.filter(user=self.request.user, pk=self.kwargs['cm'])
        if comment.exists():
            return self.destroy(request, *args, **kwargs)
        else:
            raise ValidationError("you can\'t delete another user\'s post")
ModifyComment = ModifyComment.as_view()

and the response to going to the url '<str:pk>/comments/<str:cm>/' comment of some post we get this: example of the response

补充说明,perform_update函数似乎从未被调用过,即使在函数的开头放一个print语句也不会被打印出来,因此问题可能与get\u queryset有关,即使我try 使用普通queryset=Comment.object.all()并使get\u queryset函数返回带有正确参数的注释,但我无法使其工作

推荐答案

对于单个对象,需要覆盖get_object方法.

您正在执行请求GET/str:pk/comments/str:cm/,这将调用视图上的retrieve方法,该方法将调用get_object.默认行为是试图找到id等于pkComment对象,因为这是第一个参数,因为需要过滤不同的模型,需要覆盖它.

classy drf是一个很好的网站,可以了解课程的内部工作原理.

Python相关问答推荐

无法导入已安装的模块

创建带有二维码的Flask应用程序,可重定向到特定端点

使用matplotlib pcolormesh,如何停止从一行绘制的磁贴连接到上下行?

指示组内的rejected_time是否在creation_timestamp后5分钟内

Odoo 14 hr. emergency.public内的二进制字段

为什么tkinter框架没有被隐藏?

如何标记Spacy中不包含特定符号的单词?

两个pandas的平均值按元素的结果串接元素.为什么?

Python,Fitting into a System of Equations

Python列表不会在条件while循环中正确随机化'

将pandas导出到CSV数据,但在此之前,将日期按最小到最大排序

Polars asof在下一个可用日期加入

如何使用两个关键函数来排序一个多索引框架?

幂集,其中每个元素可以是正或负""""

未调用自定义JSON编码器

如何创建引用列表并分配值的Systemrame列

如何在海上配对图中使某些标记周围的黑色边框

Python 3试图访问在线程调用中实例化的类的对象

如何在GEKKO中使用复共轭物

使用嵌套对象字段的Qdrant过滤