我在代码中添加了一些信号接收器,一切都工作正常,直到我将其推送到版本控制并且 CI/CD 管道失败。在尝试迁移时,它会抱怨:
django.db.utils.OperationalError: no such table: badges_badge
但迁移正在我的机器上进行!
CI/CD 从头开始,所以我尝试删除我的db.sqlite3
本地,然后尝试重新迁移python manage.py migrate
:
django.db.utils.OperationalError: no such table: badges_badge
因此,从现有数据库迁移是可行的,但从新数据库迁移则不行。
My signals.py
:
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from badges.badge_stuff import badges
@receiver(post_save)
def update_badges(sender, **kwargs):
for badge in badges:
badge.update()
My apps.py
:
from django.apps import AppConfig
class BadgesConfig(AppConfig):
name = 'badges'
def ready(self):
# Register signal listeners.
from . import signals
为什么它可以与现有数据库一起使用,但在初始化时却不起作用?如何解决这个问题?
我遇到了这个问题,这是因为我注册信号的方式所致。
问题是代码中apps.ready()
在任何迁移之前运行,所以如果signals.py
取决于数据库中尚不存在的模型(例如,从头开始迁移时),它会失败。当您的signals.py
导入其他模块,然后取决于您的模型。
Here, badges.badge_stuff.badges
进口Badge
模型,这是在第一次迁移时创建的。所以它找不到它。
为了解决这个问题,我们可以使用post_migrate
信号来注册我们所有的信号after任何迁移,因此将在任何信号代码运行之前创建任何必要的模型。
将上面修改为:
from django.apps import AppConfig
from django.core.signals import pre_save, post_migrate
class BadgesConfig(AppConfig):
name = 'badges'
def register_signals(self, **kwargs):
# If your signals are decorated with @receiver, the line below is all you need
from . import signals
# Otherwise, explicitly connect the signal handler
pre_save.connect(signals.my_callback)
def ready(self):
post_migrate.connect(self.register_signals, sender=self)
希望运行您的迁移现在应该可以正常工作!
请记住在以下位置注册您的应用程序INSTALLED_APPS
使用这个新的 AppConfigsettings.py
:
INSTALLED_APPS = [
...
'badges.apps.BadgesConfig',
# Or just 'badges' for Django 4.0+
...
]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)