﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
21638	Infinite migrations when using AUTH_USER_MODEL	patrick@…	Andrew Godwin <andrew@…>	"When using a custom class with AUTH_USER_MODEL, syncdb thinks that the ""username"" field in that class has changed. Every time you run
{{{
python manage.py makemigrations
}}}
it generates a new migration file, even though that model has no changes. If you run that migration, and call makemigrations again, it still thinks the field has changed and will make even more migration files. 

For example, my models.py:

{{{
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

class Person(AbstractUser):
    favorite_color = models.CharField(max_length=64)
    
}}}

0001_initial.py created by ""python manage.py makemigrations myapp""

{{{
# encoding: utf8
from django.db import models, migrations
import django.utils.timezone
import django.core.validators


class Migration(migrations.Migration):
    
    dependencies = []

    operations = [
        migrations.CreateModel(
            fields = [('id', models.AutoField(serialize=False, primary_key=True, verbose_name='ID', auto_created=True),), ('password', models.CharField(max_length=128, verbose_name='password'),), ('last_login', models.DateTimeField(default=django.utils.timezone.now, verbose_name='last login'),), ('is_superuser', models.BooleanField(default=False, verbose_name='superuser status', help_text='Designates that this user has all permissions without explicitly assigning them.'),), ('username', models.CharField(max_length=30, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, verbose_name='username', validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username.', 'invalid')]),), ('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True),), ('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True),), ('email', models.EmailField(max_length=75, verbose_name='email address', blank=True),), ('is_staff', models.BooleanField(default=False, verbose_name='staff status', help_text='Designates whether the user can log into this admin site.'),), ('is_active', models.BooleanField(default=True, verbose_name='active', help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.'),), ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined'),), ('favorite_color', models.CharField(max_length=64),), ('groups', models.ManyToManyField(to='auth.Group', verbose_name='groups', blank=True),), ('user_permissions', models.ManyToManyField(to='auth.Permission', verbose_name='user permissions', blank=True),)],
            options = {'abstract': False, 'verbose_name': 'user', 'verbose_name_plural': 'users'},
            bases = (models.Model,),
            name = 'Person',
        ),
    ]
}}}
I'm suspicious of the ""bases = (models.Model,)"" instead of ""bases=(models.AbstractUser,)"" but I don't know if that has any significance.

 
And every time I run makemigrations after this, it creates a new migration like the following (the field order changes, but the content is always the same). If you run makemigrations ten times without changing your model, you get ten new scripts that all look like this:
{{{
# encoding: utf8
from django.db import models, migrations
import django.core.validators


class Migration(migrations.Migration):
    
    dependencies = [('myapp', '0001_initial')]

    operations = [
        migrations.AlterField(
            name = 'username',
            model_name = 'person',
            field = models.CharField(validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username.', 'invalid')], verbose_name='username', max_length=30, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True),
        ),
    ]
}}}



Discovered using Python 3.3.3, and Django 1.7 (alpha) commit 23d9f517dc3ca31816bb8596f5a59f1ae44304ee

Note: I double checked this occurred with a fresh database after reading the warning [https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model here], and confirmed that AUTH_USER_MODEL was set before any tables were made."	Bug	closed	Migrations	dev	Normal	fixed		jess@… Ben Cole	Accepted	0	0	0	0	0	0
