Django - pre_delete 表示不更新实例的外键字段
Django - pre_delete signal not updating instance's foreign key field
我正在尝试为我的 Django 应用程序的 Like
模型使用 pre_delete
信号。 Like
模型有一个 Book
外键。 Book
模型有一个 num_of_likes
字段。最后,我试图从我的 pre_delete
信号更新这个 num_of_likes
字段。只是我做不到。
我的代码会把问题搞清楚,我觉得(请特别注意注释和打印语句):
书籍/models.py:
class Book(models.Model):
num_of_likes = models.IntegerField()
喜欢/models.py:
class Like(models.Model):
user = models.ForeignKey(User)
book = models.ForeignKey(Book)
喜欢/views.py:
class DeleteLikeView(APIView):
def post(self, request, book):
book = get_object_or_404(Book, id=book)
print(book.num_of_likes) # Prints, say, 10
like = Like.objects.get(user=request.user, book=book)
like.delete() # triggers signal handler below (should update `book.num_of_likes`)
print(book.num_of_likes) # Still prints 10, expected 9 <------ PROBLEM
return ...
喜欢/signals.py:
@receiver(pre_delete, sender=Like)
def delete_book_like(sender, instance, **kwargs):
print(instance.book.num_of_likes) # Prints 10
instance.book.num_of_likes -= 1
instance.book.save()
print(instance.book.num_of_likes) # Prints 9, as expected
为什么 book.num_of_likes
会在 delete_book_like
中更新,但更改不会显示在 DeleteLikeView
中?
删除视图中的 book
与信号处理程序中的 instance.book
是不同的 Python 对象。 Python 对象不会神奇地了解到底层数据库表示已更改。您可以在打印前调用 refresh_from_db
:
book.refresh_from_db()
print(book.num_of_likes)
或者干脆让 num_of_likes
成为动态评估的 属性,这样你就不必担心非规范化数据的完整性:
class Book(models.Model):
@property
def num_of_likes(self):
return self.like_set.count()
我正在尝试为我的 Django 应用程序的 Like
模型使用 pre_delete
信号。 Like
模型有一个 Book
外键。 Book
模型有一个 num_of_likes
字段。最后,我试图从我的 pre_delete
信号更新这个 num_of_likes
字段。只是我做不到。
我的代码会把问题搞清楚,我觉得(请特别注意注释和打印语句):
书籍/models.py:
class Book(models.Model):
num_of_likes = models.IntegerField()
喜欢/models.py:
class Like(models.Model):
user = models.ForeignKey(User)
book = models.ForeignKey(Book)
喜欢/views.py:
class DeleteLikeView(APIView):
def post(self, request, book):
book = get_object_or_404(Book, id=book)
print(book.num_of_likes) # Prints, say, 10
like = Like.objects.get(user=request.user, book=book)
like.delete() # triggers signal handler below (should update `book.num_of_likes`)
print(book.num_of_likes) # Still prints 10, expected 9 <------ PROBLEM
return ...
喜欢/signals.py:
@receiver(pre_delete, sender=Like)
def delete_book_like(sender, instance, **kwargs):
print(instance.book.num_of_likes) # Prints 10
instance.book.num_of_likes -= 1
instance.book.save()
print(instance.book.num_of_likes) # Prints 9, as expected
为什么 book.num_of_likes
会在 delete_book_like
中更新,但更改不会显示在 DeleteLikeView
中?
删除视图中的 book
与信号处理程序中的 instance.book
是不同的 Python 对象。 Python 对象不会神奇地了解到底层数据库表示已更改。您可以在打印前调用 refresh_from_db
:
book.refresh_from_db()
print(book.num_of_likes)
或者干脆让 num_of_likes
成为动态评估的 属性,这样你就不必担心非规范化数据的完整性:
class Book(models.Model):
@property
def num_of_likes(self):
return self.like_set.count()