我正在使用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
如何从数据库中删除我的投票记录?
答案 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)