【问题标题】:How to execute code on post_migrate signal in Django?如何在 Django 中对 post_migrate 信号执行代码?
【发布时间】:2015-12-03 11:43:47
【问题描述】:

我正在为我的项目进行某种重构,我依赖 django django.contrib.auth.models.Permission 模型。到目前为止,我使用 post_save 信号为每个新用户定义了权限,因此在创建用户时,我使用 user.user_permissions.add(the_permission) 分配他们的权限,这非常有效。

现在我想使用django.contrib.auth.models.Group 模型来分类用户应该拥有的权限。

这是我的代码:

from django.apps import AppConfig
from django.db.models.signals import post_migrate
from django.contrib.auth.models import Group, Permission


def create_group(name, permissions):
    group = Group.objects.create(name=name)
    [group.permissions.add(permission) for permission in permissions]


def define_company_groups(sender, **kwargs):
    permissions = [
        Permission.objects.get(codename='add_mymodel'),
        Permission.objects.get(codename='change_mymodel'),
    ]
    create_group('managers', permissions)


class MyAppConfig(AppConfig):
    name = 'players'
    verbose_name = 'The players app'

    def ready(self):
        post_migrate.connect(define_company_groups, sender=self)

定义此代码后,我希望在调用./manage.py migrate 后应该触发此处理程序。但这并没有发生,我得到的只是:

Running post-migrate handlers for application players
Adding permission 'players | mymodel | Can add mymodel'
Adding permission 'companies | company | Can change mymodel'
Adding permission 'companies | company | Can delete company'

我找到了这篇 https://groups.google.com/forum/#!topic/django-developers/8MdaWtJp4VQ 文章,他们说我应该在名为 management.py 的文件中定义我的 post_migrate 处理程序,但它对我不起作用。

最后,我的问题是:我应该把这个代码放在我的自定义 post_migrate 信号的哪里?

【问题讨论】:

  • 你如何告诉 Django 使用MyAppConfig?在您的INSTALLED_APPS 设置中?
  • 其实只要把应用名称加到INSTALLED_APPS元组里,应该够用还是应该再添加一个配置?

标签: django django-signals django-migrations


【解决方案1】:

Django docs 建议在您的应用配置的 ready 方法中连接 post_migrate 信号。您链接到的 Google 群组帖子已过时,在文档更新之前。

您还需要在INSTALLED_APPS 设置中设置specify the app config

INSTALLED_APPS = [
    'myapp.apps.MyAppConfig',
    # ...
]

另一种配置应用的方法是在应用的__init__.py 中使用default_app_config。见Configuring Applications。但是另一种方式(AppConfig 的虚线路径)是首选。

【讨论】:

    【解决方案2】:

    信号 post_migrate 与其他信号不同。 './manage.py' 命令不会执行来自 apps.py 文件或 signals.py 文件的代码 要执行此信号,请将其放在 models.py 文件中。 然后你会得到想要的结果

    【讨论】:

      【解决方案3】:

      我之前为另一个问题做过 post_migrate 示例。我会写下它的解决方案。或许对你有帮助。

      # in apps.py
      
      ...
      from django.conf import settings
      from django.db.models.signals import post_migrate
      
      def create_default_site_profile(sender, **kwargs):
          """after migrations"""
          from django.contrib.sites.models import Site
          from core.models import SiteProfile
      
          site = Site.objects.get(id=getattr(settings, 'SITE_ID', 1))
      
          if not SiteProfile.objects.exists():
              SiteProfile.objects.create(site=site)
      
      class CoreConfig(AppConfig):
          name = 'core'
      
          def ready(self):
              post_migrate.connect(create_default_site_profile, sender=self)
              
              # if you have other signals e.g. post_save, you can include it 
              # like the one below.
              from .signals import (create_site_profile)  
      

      【讨论】:

        猜你喜欢
        • 2016-06-10
        • 1970-01-01
        • 2023-02-06
        • 2016-12-06
        • 2011-10-06
        • 1970-01-01
        • 2011-03-30
        • 2015-05-07
        • 1970-01-01
        相关资源
        最近更新 更多