Repository: django-cms/django-cms

Issue:
migration issue after changing template choices [1.7] 
After adding custom templates in setting file:

```
CMS_TEMPLATES = (
    ('cms/content_even.html', 'Template for even number boxes'),
    ('cms/content_odd.html', 'Template for odd number boxes'),
)
```

When I run makemigrations command, it seems to create separate migration file like this:

```
migrations.AlterField(
            model_name='page',
            name='template',
            field=models.CharField(default=b'INHERIT', help_text='The template used to render the content.', max_length=100, verbose_name='template', choices=[(b'cms/content_even.html', 'Template for even number boxes'), (b'cms/content_odd.html', 'Template for odd number boxes'), (b'INHERIT', 'Inherit the template of the nearest ancestor')]),
        )
]
```

This will force us to create migration script every time we change template choices.



Discussion:
I've seen this issue as well but this is true of any model with `choices` specified. It seems to be a Django 1.7 issue and not specific to django-cms.

I added a ticket upstream => https://code.djangoproject.com/ticket/23581

Good spot

Looks like Django is claiming that this is intended behavior?  From the open ticket: 

> It's by design that migrations are generated even if no database changes are required (see #22837 for the rationale). We should probably document this if it's not already as this is becoming a FAQ.
> We should also look into if we can avoid the DROP DEFAULT SQL when it's not required.

And from a [previous issue](https://code.djangoproject.com/ticket/22837) on the same topic: 

> This is by design. There are several reasons, not least of which for me that datamigrations at points in history need to have a full accurate representation of the models, including all their options not just those which affect the database.

Right, but in this case there is no such thing as a "full accurate representation of the models" since every single install of django-cms presumably has a different settings.CMS_TEMPLATES, the representations are legion.

@jsma:  What's the path forward if Django doesn't change this behavior?

Agree. If it's by design looks like a bad design decision
Marking this as blocker for 3.0.6, as I don't see any way to workaround this.
Possibly we can use custom fields type and custom migration mechanism to fix this for the involved fields (as pointed out in  #3474 UserSettings.language might be also affected), but it's definitely a nasty way to solve this

I'll pursue this upstream and report back hear if I learn anything new.

I CCed myself

Thanks for the help on these PRs @yakky!  Thanks @jsma for working on this.


Resolving patch:
diff --git a/cms/migrations_django/0001_initial.py b/cms/migrations_django/0001_initial.py
--- a/cms/migrations_django/0001_initial.py
+++ b/cms/migrations_django/0001_initial.py
@@ -4,7 +4,10 @@
 from django.db import models, migrations
 from django.conf import settings
 import django.utils.timezone
+from cms.utils.conf import get_cms_setting
+from django.utils.translation import ugettext_lazy as _
 
+template_choices = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
 
 class Migration(migrations.Migration):
 
@@ -86,7 +89,7 @@ class Migration(migrations.Migration):
                 ('soft_root', models.BooleanField(db_index=True, default=False, help_text='All ancestors will not be displayed in the navigation', verbose_name='soft root')),
                 ('reverse_id', models.CharField(db_index=True, max_length=40, verbose_name='id', null=True, help_text='A unique identifier that is used with the page_url templatetag for linking to this page', blank=True)),
                 ('navigation_extenders', models.CharField(db_index=True, max_length=80, blank=True, verbose_name='attached menu', null=True)),
-                ('template', models.CharField(max_length=100, default='INHERIT', help_text='The template used to render the content.', verbose_name='template', choices=[('col_two.html', 'two columns'), ('col_three.html', 'three columns'), ('nav_playground.html', 'navigation examples'), ('simple.html', 'simple'), ('static.html', 'static placeholders'), ('INHERIT', 'Inherit the template of the nearest ancestor')])),
+                ('template', models.CharField(max_length=100, default='INHERIT', help_text='The template used to render the content.', verbose_name='template', choices=template_choices)),
                 ('login_required', models.BooleanField(default=False, verbose_name='login required')),
                 ('limit_visibility_in_menu', models.SmallIntegerField(db_index=True, default=None, verbose_name='menu visibility', null=True, choices=[(1, 'for logged in users only'), (2, 'for anonymous users only')], help_text='limit when this page is visible in the menu', blank=True)),
                 ('is_home', models.BooleanField(db_index=True, default=False, editable=False)),


Test patch: