Django:发布“初始迁移后”的信号

时间:2018-05-03 09:23:35

标签: django django-signals

为了设置新的开发系统,我希望有一个“发布初始迁移”信号。

似乎这样的事情还不存在。

详细说明:我想要一个在初始迁移运行后运行的信号。第二次调用“manage.py migrate”不应发出此信号。

使用案例:我想设置基本数据(添加一些用户和组,为“example.com”添加一些虚拟数据,......)。

我不想为此使用迁移,因为在迁移中我只有返回的有限模型。

相同的灯具:我不想使用灯具,因为如果我拥有真正的ORM模型,我的任务完成得更少痛苦。

有办法解决它吗?

2 个答案:

答案 0 :(得分:8)

您可以使用post_migrate信号。检查您的虚拟数据是否已创建(例如if User.objects.exists():),如果已创建,则停止。

答案 1 :(得分:3)

@ Alasdair的建议post-migrate signal听起来不错,但无论如何我还要增加两美分。

在我需要初始数据的过去情况下(例如超级用户和一些基本配置数据)我使用custom admin command来确保存在一些初始数据。在这些情况下,固定装置并没有完全达到我所需的水平。

这个管理命令必须是幂等的,因为只有在尚未达到所需状态时才会进行更改。

例如,我的ensure_auth_data命令看起来像这样:

class Command(BaseCommand):
    help = 'Creates superuser, permissions and groups.'

    def _ensure_superuser(self):
        u_created = False
        u_updated = False
        try:
            usr = User.objects.get(username='ralf')
        except User.DoesNotExist:
            usr = User()
            usr.username = 'ralf'
            u_created = True

        if not usr.is_active:
            usr.is_active = True
            u_updated = True
        if not usr.is_superuser:
            usr.is_superuser = True
            u_updated = True

        if u_created or u_updated:
            usr.save()

        if u_created:
            self.stdout.write('Created superuser "{}"'.format(usr.username))
        elif u_updated:
            self.stdout.write('Updated superuser "{}"'.format(usr.username))
        else:
            self.stdout.write('Superuser "{}" already up to date'.format(usr.username))

    def _ensure_permissions(self):
        # create some special permissions if they're not present

    def _ensure_groups(self):
        # create some special groups and assign them permissions

    def handle(self, *args, **options):
        self.stdout.write('Starting command')
        self.stdout.write('...')
        self._ensure_superuser()
        self.stdout.write('...')
        self._ensure_permissions()
        self.stdout.write('...')
        self._ensure_groups()
        self.stdout.write('...')
        self.stdout.write('Command finished')