Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Django create migration files for proxy models?

Tags:

I just created a proxy model and was surprised that manage.py makemigrations creates a new migration file with a migrations.CreateModel operation.

A proxy model does not create a new database table, it's just a different python interface to the same dataset and indeed manage.py sqlmigrate my_app_label 0042 returns nothing.

I thought that it might be used to create the proxy model ContentType but those are created on demand if they don't exist.

Is it used to trigger the creation of the proxy model permissions? There's a 6 year old open bug on proxy model permissions so I'm not really sure how this part is supposed to work now...

It used Django 1.8 to test this.

Edit: to clarify, Django creates a migration that does nothing for new proxy models so wouldn't we want Django to not create the migration in the first place if it's of no use?

Is there a use case where it would be useful to have the migration?

like image 353
Maxime R. Avatar asked Jun 23 '16 10:06

Maxime R.


2 Answers

Ah, but if you open the migration in your editor, you will find that it's actually an empty migration! Here is an example

class Migration(migrations.Migration):
    dependencies = [
        ('stackoverflow', '0009_auto_20160622_1507'),
    ]

    operations = [
        migrations.CreateModel(
            name='MyArticle',
            fields=[
            ],
            options={
                'proxy': True,
            },
            bases=('stackoverflow.article',),
        ),
    ]

And if you run ./manage.py sqlmigrate myapp 0010 (which is the number that corresponds to my migration above), what you get is what's on the next line (nothing).

This is because the fields section of the migration is empty and option includes proxy = True. This setting prevents any SQL from being executed for this migration, and the original table is left untouched.

So you may ask, why does Django bother to create an empty migration? That's because the proxy model may be referred to by another model in a future migration.

like image 146
e4c5 Avatar answered Nov 15 '22 14:11

e4c5


I believe migrations are generated because the databases is affected and migrations are how Django signals database changes. The structure is not changed, but entries are added in (at least) two tables:

  • A new ContentType is added to django_content_type for the proxy model.
  • Permissions specific to the Proxy Model are added to auth_permission. I assume this "always" happens unless the proxy uses the exact same class name. It certainly does happen -- we actually use a proxy model to access User using different permissions without touching the default User model.

Both of these details are actually noted in the comment chain of the issue linked by the OP (e.g. comment #31) because they contribute to the bug (i.e. that Django looks for permissions in a different app than those actually generated in auth_permissions).

like image 29
claytond Avatar answered Nov 15 '22 12:11

claytond