All notes


Migrations are Django’s way of propagating changes you make to your models (adding a field, deleting a model, etc.) into your database schema.

You should think of migrations as a version control system for your database schema.

makemigrations is responsible for packaging up your model changes into individual migration files - analogous to commits - and migrate is responsible for applying those to your database.

The migration files for each app live in a “migrations” directory inside of that app, and are designed to be committed to, and distributed as part of, its codebase.

You should be making them once on your development machine and then running the same migrations on your colleagues’ machines, your staging machines, and eventually your production machines.



    applying migrations, as well as unapplying and listing their status.
    creating new migrations based on the changes you have made to your models.
    displays the SQL statements for a migration.
    lists a project’s migrations.

# Dump and load data
python dumpdata [appname] > appname_data.json
python loaddata appname_data.json
# Dump auth.User data
python dumpdata auth.User --indent 4 > users.json

# To delete migrations, remove all files in "migrations" directory except for "":
find . -path "*migrations*" -name "*.py" -not -path "*__init__*" -exec rm {} \;

python squashmigrations schools 0002

在使用SQLite3数据库时, 因为SQLite3 不支持删除列操作,只有有限地 ALTER TABLE 支持,所以修改数据库列的操作被新建表然后select into newtable 代替,所以会存在更多问题。


After adding a field or removing a model:

python makemigrations
# Or use a different name by --name:
python makemigrations --name changed_my_model 

python migrate

Once the migration is applied, commit the migration and the models change to your version control system as a single commit - that way, when other developers (or your production servers) check out the code, they’ll get both the changes to your models and the accompanying migration at the same time.


Error: django migrate cannot serialize bound method

ValueError: Cannot serialize: <bound method ShortUUID.uuid of <shortuuid.main.ShortUUID object at 0x00000222D7EB5EB8>>

SO: migration cannot serialize a class method.

As explained in Django's migrations docs, Django can serialize function and method references, (in Python 3) unbound methods used from within the class body, and a bunch of other stuff, but it can't serialize everything.

In this case, because you've made get_default a @classmethod, Car.get_default is a bound method (i.e., it takes an implicit reference to Car as its first parameter), rather than a plain function or method reference, and Django doesn't know what to do with that.

Try making get_default a @staticmethod instead, or make a free function (top-level function) that calls Car.get_default.

wcfSolution: defind a free function and use this function for default:

def populateUuid():
  return shortuuid.uuid

# Create your models here.
class BaseModel(models.Model):
  uuid = ShortUUIDField(unique=True, default=populateUuid, editable=False, db_index=True, blank=False)
  class Meta:
    abstract = True

Add initial data

djangoProject: RunPython.

Write your own migration file, with migrations.RunPython:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models

def forwards_func(apps, schema_editor):
    # We get the model from the versioned app registry;
    # if we directly import it, it'll be the wrong version
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
        Country(name="USA", code="us"),
        Country(name="France", code="fr"),

def reverse_func(apps, schema_editor):
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).filter(name="USA", code="us").delete()
    Country.objects.using(db_alias).filter(name="France", code="fr").delete()

class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.RunPython(forwards_func, reverse_func),

django squashmigrations invalid syntax with runpython

google groups: django squashmigrations invalid syntax with runpython<.

It was because python cannot import from modules that starts with numbers. Also, the idea was that we shouldn't use the migration files as modules to import code from, that's why the file name stayed as it was. Users should manually move their RunPython methods manually and resolve those invalid references to migration files.

wcfNote: don't prefix numbers to your RunPython migration files.