Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access django-custom-user manager method in migration

I'd like to seed a superuser record in a data migration for a django 1.7 project. I'm using the django-custom-user app. My migration looks like this:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

def load_data(apps, schema_editor):
    EmailUser = apps.get_model('custom_user', 'EmailUser')
    root = EmailUser.objects.create_superuser(email='[email protected]', password='supersecure')


class Migration(migrations.Migration):
    dependencies = [
        ('accounts', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(load_data)
    ]

When running ./manage.py migrate I get the following error:

Running migrations:
  Applying accounts.0002_initial_data...Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 161, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/usr/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 68, in migrate
    self.apply_migration(migration, fake=fake)
  File "/usr/local/lib/python2.7/site-packages/django/db/migrations/executor.py", line 102, in apply_migration
    migration.apply(project_state, schema_editor)
  File "/usr/local/lib/python2.7/site-packages/django/db/migrations/migration.py", line 105, in apply
    operation.database_forwards(self.app_label, schema_editor, project_state, new_state)
  File "/usr/local/lib/python2.7/site-packages/django/db/migrations/operations/special.py", line 117, in database_forwards
    self.code(from_state.render(), schema_editor)
  File "/Users/spoolphiz/work/somesite/accounts/migrations/0002_initial_data.py", line 14, in load_data
    root = EmailUser.objects.create_superuser(email='[email protected]', password='f00b@r')
AttributeError: 'Manager' object has no attribute 'create_superuser'

I see that EmailUserManager does have a create_superuser method. Am I incorrectly invoking the manager's function?

Edit:

I see the same issue here. Is duplicating all code really the best solution? Seems like at that point I'd be better off using RunSQL and manually performing the inserts.

like image 348
novon Avatar asked Mar 01 '15 00:03

novon


1 Answers

I'm seeing the same issue as @cpury in 1.8.4. I set use_in_migrations=True in my manager but unexpectedly the custom manager method is not available in a data migration using Model.objects.my_custom_method(), giving the same error above. The workaround I did was to import the manager and instantiate it. The problem then was that self.model is None since it is unattached to the model. So then I did the following and it seems to work, although I don't understand why the use_in_migrations flag doesn't work as I expected.

from appname.managers import MyManager
def add_data(apps, schema_editor):
    mgr = MyManager()
    mgr.model = apps.get_model('appname', 'Model')
    mgr.my_method_that_adds_data()

Edit: It looks like the AlterModelManagers operation which sets the custom manager for the model had not been created yet and it showed up in a later migration. I might have forgotten to run 'makemigrations' before 'makemigrations --empty'. I moved this operation before the RunPython call to add_data() but still get the AttributeError.

like image 70
ybendana Avatar answered Oct 25 '22 02:10

ybendana