﻿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
28438	Initial migration creates fields not listed in the migration if mixin class changes	Michal Dabski	nobody	"Consider the sample model with a mixin class:
{{{
from django.db import models

class TestMixin(object):
    pass


class TestModel(TestMixin, models.Model):
    sample_field = models.CharField(max_length=20)
}}}

When running makemigrations, django creates a perfectly good and valid migration:
{{{
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-07-26 17:03
from __future__ import unicode_literals

from django.db import migrations, models
import migration_test.models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='TestModel',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('sample_field', models.CharField(max_length=20)),
            ],
            bases=(migration_test.models.TestMixin, models.Model),
        ),
    ]

}}}
SQL:

{{{
BEGIN;
--
-- Create model TestModel
--
CREATE TABLE ""migration_test_testmodel"" (""id"" serial NOT NULL PRIMARY KEY, ""sample_field"" varchar(20) NOT NULL);
COMMIT;
}}}



Next, refactor mixin class to add a field to it - need to change mixin's base class to {{{models.Model}}}, otherwise field will not be correctly inherited by models:
{{{
class TestMixin(models.Model):
    mixin_field = models.CharField(max_length=20, default='test')

    class Meta:
        abstract = True
}}}

This creates a new migration which adds {{{mixin_field}}} to it - nothing special. However, when applying both migrations after the model changes, second migration fails with the following error {{{django.db.utils.ProgrammingError: column ""mixin_field"" of relation ""migration_test_testmodel"" already exists}}}. as it turns out, the first migration's SQL has now changed to include {{{mixin_field}}}:
{{{
BEGIN;
--
-- Create model TestModel
--
CREATE TABLE ""migration_test_testmodel"" (""id"" serial NOT NULL PRIMARY KEY, ""mixin_field"" varchar(20) NOT NULL, ""sample_field"" varchar(20) NOT NULL);
COMMIT;
}}}
The python code of the migration obviously has not changed, but the resulting SQL did, and it includes a field not explicitly listed in the migration's {{{fields}}}.

Note:
- this does not happen if the mixin class extends {{{models.Model}}} to begin with.
- if model extends a mixin that extends {{{object}}}, it ends up in model's {{{bases}}}, however if mixin extends {{{model.Model}}} it does not.
- when mixin's base class changes, schema migration does not reflect this change in model's {{{bases}}}

Tested with Django 1.11.3, Python 2.7

Proposed solution:
migration should not create database fields for model fields not explicitly listed in {{{fields}}}"	Bug	new	Migrations	1.11	Normal		migration,models,mixin,postgresql		Accepted	0	0	0	0	0	0
