Skip to main content
 首页 » 编程设计

python之Django model.delete() 方法返回成功删除但实际上没有删除

2025年01月19日24daizhj

我正在使用 Django 2.0。

我对 Django 中的一个函数进行了 AJAX 调用,该函数应允许用户对帖子投票或从帖子中删除他们的投票。当我在模型上调用 .delete() 方法时,模型返回一个结果,就好像它正在被删除一样,但记录并没有从数据库中删除。这是 Django 函数:

if request.method != 'POST': 
    raise Http404 
 
post_id = request.POST.get('postId') 
vote_type = request.POST.get('voteType') 
 
# If vote_type isn't valid, 404 
if (not any(vote_type in allowed_vote_type 
        for allowed_vote_type in Vote.ALLOWED_VOTE_TYPES) 
        or not 'null'): 
    raise Http404 
 
post_queryset = Post.objects.filter(pk=post_id) 
post = get_object_or_404(post_queryset) 
 
try: 
    vote = Vote.objects.get( 
        post=post, 
        user=request.user 
    ) 
    print('Vote object found') 
    # User has already voted on this post. 
    # Update user's vote. 
    if vote_type == 'upvote': 
        print('vote_type is upvote') 
        if vote.vote_type == 'upvote': 
            print('Deleting vote.') 
            # User just upvoted twice. Expected behavior: Remove their vote 
 
            ################## 
            ## THIS IS MY PROBLEM 
            ################## 
            vote_delete_result = vote.delete() 
            print(vote_delete_result) 
            if vote_delete_result[0]: 
                # If upvote was successfully deleted, reduce post score 
                post.score -= 1 
            ################## 
            ## END PROBLEM 
            ################## 
        elif vote.vote_type == 'downvote': 
            print('Changing from downvote') 
            # User is changing from downvote to upvote 
            vote.vote_type = vote_type 
            # Add 2 to post.score 
            post.score += 2 
        else: 
            print('Vote type was not downvote, so we did nothing.') 
    elif vote_type == 'downvote': 
        # Repeat all the stuff above, but for downvote... 
except ObjectDoesNotExist: 
    print('Vote object NOT found') 
    # User has not yet voted on this post. 
    # Create a new vote. 
    vote = Vote( 
        user=request.user, 
        post=post, 
        vote_type=vote_type, 
    ) 
 
    # Update post score. 
    if vote_type == 'upvote': 
        post.score += 1 
    elif vote_type == 'downvote': 
        post.score -= 1 
 
if vote: 
    vote.save() 
post.save() 
data = serializers.serialize( 
    'json', 
    post_queryset, 
    fields=('id','score') 
) 
return HttpResponse(data, content_type='application/json') 

当调用 vote_delete_result = vote.delete() 时,vote_delete_result 的值为 (1, {'posts.Vote': 1}) 正如预期的那样according to the docs .

不同于this question where the model.delete() method is not triggered ,我们知道正在调用 model.delete() 方法,因为 vote_delete_result 返回一个确认它的元组。

One Google Group discussed the idea that .delete() only worked on QuerySets但那篇文章是在 2012 年发布的。Django 2.0 文档建议 model.delete() 应该可以正常工作。即便如此,我还是像这样使用 QuerySet 测试了我的问题(仍然遇到同样的问题):

vote_delete_result = Vote.objects.filter(pk=vote.id).delete() 
print(vote_delete_result) 
if vote_delete_result[0]: 
    post.score -= 1 

如何从数据库中删除我的投票记录?

请您参考如下方法:

好吧,我将提出一些建议,也许你会喜欢它们。

<强> 1。不要创建单独的模型来记录投票

您可以创建两个多对多字段来记录赞成者和反对者:

class Post: 
    upvoters = ManyToManyField(User) 
    downvoters = ManyToManyField(User) 

现在,如果用户给帖子点赞,您所要做的就是将该用户添加到 upvoters 字段:

if vote_type == upvote: 
    if already upvoted: 
        # undo vote 
        post.upvoters.remove(user) 
    else: 
        # add vote 
        post.upvoters.add(user) 

同样适用于否决票。


<强> 2。在模型方法中移动赞成票/反对票逻辑

我曾经创建了一个项目,其中大部分与模型相关的逻辑都在 View 中,后来我后悔了很久。组织代码的更好方法是尽可能将与数据库相关的逻辑保留在模型中,并将与前端/模板相关的逻辑保留在 View 中。

因此,要将所有赞成票/反对票逻辑转移到您的模型中,您可以为此创建特殊方法:

class Post: 
    ... 
    def vote(self, user, vote_type): 
        if vote_type == upvote: 
            self.upvoters.add(user) 
 
        # and so on 

然后,您可以调用Post.vote 方法进行投票:

post.vote(request.user, vote_type)