0

I want to create two groups once per project's life. So, I read about AppConfig

And I created core.appconfig.py:

from django.apps import AppConfig
from django.contrib.auth.models import Group

class RolesConfig(AppConfig):
    name = 'roles_config'
    verbose_name = 'Roles configuration'
    def create_roles(self):
        driver = Group.objects.create(name='driver')
        manager = Group.objects.create(name='manager')
        driver.save()
        manager.save()

And the in settings.py: default_app_config = 'core.appconfig.RolesConfig' But when I run server and go to the admin page, there are no groups. Why? When is AppConfig called?

Community
  • 1
  • 1
Andrew
  • 423
  • 1
  • 6
  • 16

3 Answers3

4

Consider using a data migration:

  1. Create an empty migration file with manage.py makemigrations <app_name> --empty.
  2. Create a function that adds the default values to the database.
def create_roles(apps, schema_editor):
    Group = apps.get_model('auth', 'Group')
    driver = Group.objects.create(name='driver')
    manager = Group.objects.create(name='manager')
  1. Add a RunPython operation to you migrations:
class Migration(migrations.Migration):
    operations = [
        migrations.RunPython(create_roles),
    ]

Automatic loading of data fixtures has been deprecated in favour of data migrations.

knbk
  • 52,111
  • 9
  • 124
  • 122
  • add `RunPython` to `__init__.py` or to `0001_initial.py`? And what if I have already migrations directory in that app? – Andrew May 26 '15 at 17:12
  • In the file created by `makemigrations` in step 1. It doesn't matter if you had previous migrations, it will create a new migration that depends on the older migrations. Your `__init__.py` should be empty. Be sure to read through [the documentation](https://docs.djangoproject.com/en/1.8/topics/migrations/#data-migrations), as I might have missed something. – knbk May 26 '15 at 17:18
  • a question about this: `Group = apps.get_model('myapp', 'Group')`. Group is a python's model, so what app should I write? – Andrew May 26 '15 at 17:23
  • The `app_label` defaults to the last component of the app's name, i.e. the `auth` part of `django.contrib.auth`. – knbk May 26 '15 at 17:28
  • when doing `migrate` next error: `LookupError: No installed app with label 'django.contrib.auth'. ` – Andrew May 26 '15 at 17:34
  • You need the app label (`auth`), not its name (`django.contrib.auth`). – knbk May 26 '15 at 17:36
3

I consider @Leistungsabfall answer to be correct, apart from that: don't do this. App config was not built for this purpose, instead you should create fixtures: https://docs.djangoproject.com/en/1.8/howto/initial-data/ .

App config is run every time you run the application so it would not really work.

Visgean Skeloru
  • 2,237
  • 1
  • 24
  • 33
  • I totally agree with you. – Leistungsabfall May 26 '15 at 16:27
  • when deploying my site, I guess that `fixtures` won't work on server. Or Am I wrong? I used to use fixtures, my just to load some initial data, and always had to run `loaddata`. But how to do it without writing `loaddata` and it creates two groups automatically? – Andrew May 26 '15 at 16:31
  • You are wrong, fixtures will absolutely work on your server, besides you should only run it once - when you create DB. Also fixtures wont create duplicities as long as you also specify primary key value. – Visgean Skeloru May 26 '15 at 16:37
1

There are several things wrong here:

  1. Make sure the path to appconfig.py is myapp/appconfig.py.

  2. Make sure that name is your Django application name (e.g. myapp).

  3. Rename create_roles(self) to ready(self).

  4. In myapp/__init__.py (create this file if it doesn't exist) add this line:

    default_app_config = 'myapp.appconfig.RolesConfig'
    
  5. Remove driver.save() and manager.save(), they are redundant because create() already does save the objects in the database.

(Replace myapp with your Django application name.)

Leistungsabfall
  • 6,368
  • 7
  • 33
  • 41