Как выполнить код на сигнале post_migrate в Django?

Я делаю какой-то рефакторинг для своего проекта, где я полагаюсь на модель 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 говорится, что я должен определить свой обработчик post_migrate внутри файла с именем management.py, но у меня это не работает.

Наконец, вот мой вопрос: Где я должен поместить этот код для моего пользовательского сигнала post_migrate?


person slackmart    schedule 07.09.2015    source источник
comment
Как вы говорите Джанго использовать MyAppConfig? В вашей настройке INSTALLED_APPS?   -  person Alasdair    schedule 08.09.2015
comment
На самом деле достаточно просто добавить имя приложения в кортеж INSTALLED_APPS, или мне нужно добавить еще одну конфигурацию?   -  person slackmart    schedule 08.09.2015


Ответы (3)


В документах Django рекомендуется подключить сигнал post_migrate в вашем приложении. готовый метод конфигурации. Группы Google, на которые вы ссылаетесь, устарели до того, как документы были обновлены.

Вам также необходимо указать конфигурацию приложения в ваша настройка INSTALLED_APPS.

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

Другой способ настроить ваше приложение — использовать default_app_config в __init__.py вашего приложения. См. Настройка приложений. Но другой путь (пунктирный путь к AppConfig) предпочтительнее.

person Alasdair    schedule 07.09.2015

Раньше я делал пример 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)  
person Py Data Geek    schedule 10.10.2020

Сигнал post_migrate отличается от других сигналов. Команда «./manage.py» не будет выполнять код из файлов apps.py или signal.py. Чтобы выполнить этот сигнал, поместите его в файл models.py. Тогда вы получите желаемый результат

person user11614811    schedule 21.10.2019