Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute code on post_migrate signal in Django?

I'm doing some kind of refactoring for my project, where I'm relying on the django django.contrib.auth.models.Permission model. So far I define the permissions for each new user using a post_save signal, so when the user is created, I assign their permissions using user.user_permissions.add(the_permission), this works perfectly.

Now I want to use the django.contrib.auth.models.Group model to clasify the permissions a user should have.

This is my code:

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)

After define this code, I'm expecting that after call ./manage.py migrate this handler should be fired. But it doesn't happen, all I got is:

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'

I found this https://groups.google.com/forum/#!topic/django-developers/8MdaWtJp4VQ article, they say I should define my post_migrate handler inside a file named management.py, but it does not work for me.

Finally, here's my question: Where should I put this code for my custom post_migrate signal?

like image 280
slackmart Avatar asked Sep 07 '15 22:09

slackmart


1 Answers

I have had done a post_migrate example for another question before. I will write down its solution. Maybe it will be helpful for you.

# 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)  
like image 88
Py Data Geek Avatar answered Oct 12 '22 10:10

Py Data Geek