python - 连接到 pre_delete 信号后未调用 Django 信号接收器
问题描述
目标
我正在尝试实现一个投票系统来跟踪用户何时对数据库中的特定对象进行投票。我正在使用一个中间UserVote
模型来跟踪这一点,该模型具有实际包含所有投票的对象的外键。每当UserVote
被删除时,我想删除对相关对象的投票。
我试过的
由于批量删除不调用model.delete()
方法pre_delete
,我想通过监听信号来完成上述操作。
当我使用 Django 测试运行器测试以下接收器功能时,一切都按预期运行
from myapp.models.users import UserVote
from django.db.models.signals import pre_delete
from django.dispatch import receiver
@receiver(pre_delete)
def user_vote_handler(sender, instance, **kwargs):
if sender in UserVote.__subclasses__():
# remove the vote from the related model
问题
当我delete()
在views.py 中调用模型实例时,不会调用该函数。如果我如下向接收器函数添加打印语句,则不会打印任何语句。
from myapp.models.users import UserVote
from django.db.models.signals import pre_delete
from django.dispatch import receiver
@receiver(pre_delete)
def user_vote_handler(sender, instance, **kwargs):
print('function called')
if sender in UserVote.__subclasses__():
print('condition met')
# remove the vote from the related model
我已经阅读了Signal Documention,但没有找到问题的根源。我已经将接收器功能放入myapp.signals
和放入myapp.models.users
,并且行为是相同的。我有一种感觉,我做了一些愚蠢的事情,却没有意识到。任何人都可以阐明可能出了什么问题吗?我正在使用 Django 2.2。
代码
# models.records.py
...
class Record(models.Model):
...
# some functions for all Record subclasses
....
class Author(Record):
name = models.CharField(max_length=255)
comments = models.ManyToManyField(
Comment,
through='ForumComment',
through_fields=('author', 'comment'),
)
...
# some functions specific to this
....
...
# more records
...
# models.comments.py
...
class RecordComment(models.Mode):
text = label = models.CharField(max_length=255)
...
# some methods
...
class AuthorComment(RecordComment):
...
# methods specific to AuthorComment
...
...
# more RecordComment subclass
...
class Comment(models.Model):
class Meta:
abstract = True
up_votes = models.PositiveIntegerField(blank=True, default=0)
down_votes = models.PositiveIntegerField(blank=True, default=0)
class ForumComment(Comment):
author = models.ForeignKey('myapp.Author', on_delete=models.CASCADE, verbose_name='related record')
comment = models.ForeignKey(AuthorComment, on_delete=models.CASCADE)
...
# more types of comments
...
# models.users.py
...
class User(AbstractUser):
pass
class UserVote(models.Model):
"""shared fields and functions for UserVote models"""
class Meta:
abstract = True
DOWN_VOTE = 'DOWN'
UP_VOTE = 'UP'
VOTE_CHOICES = [
(DOWN_VOTE, 'Down vote'),
(UP_VOTE, 'Up vote'),
]
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
vote = models.CharField(choices=VOTE_CHOICES, default=UP_VOTE, max_length=255)
...
# methods to handle voting
...
class ForumCommentUserVote(UserVote):
forum_comment = models.ForeignKey('myapp.ForumComment', on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(fields=['forum_comment', 'user'], name='unique_author_tag_assignment_user_vote')
]
...
# some more methods
...
...
# more UserVote subclasses
...
解决方案
在您的应用程序 app.py 文件中为信号添加导入,它应该如下所示
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
在 settings.py 你应该像这样添加你的应用程序
'users.apps.UsersConfig',
这应该会触发 pre_delete 信号,:D 我花了一整天的时间以为我做错了什么,而实际上我只是忘记了这两个大声笑
推荐阅读
- javascript - Bootstrap 4:将按钮组转换为小屏幕的下拉菜单
- c# - CEFSharp jquery 代码不起作用
- android - Android ScrollView 在键盘出现时不滚动,而是使布局更小
- c++ - 对象成员变量还是继承?
- multidimensional-array - 如何通过对 3D 数组中的每个值求和来返回 2D 数组
- excel - 单独计算细胞变化
- vulkan - 是否应该尽量减少应用程序创建的命令池的数量?
- r - R-更改行顺序并保持列对一致
- python - 将 TFRecord 转换回 JPEG 图像
- ruby-on-rails - 如何通过整数值更改时区?