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

时间:2017-12-30 11:32:34

标签: python django

我正在使用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年.Dangang 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 个答案:

答案 0 :(得分:1)

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

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

您可以创建两个多对多字段来记录upvoters和downvoters:

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)

同样适用于downvoting。

<强> 2。在模型方法中移动upvote / downvote逻辑

我曾经创建了一个项目,其中我的大多数模型相关逻辑都在视图中,我后来很后悔。组织代码的更好方法是尽可能地保持模型中与数据库相关的逻辑,以及视图中的前端/模板相关逻辑。

因此,要将所有upvote / downvote逻辑移动到模型中,您可以为此创建特殊方法:

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

        # and so on

然后,您可以调用Post.vote方法进行upvote / downvote:

post.vote(request.user, vote_type)