Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #21290: Documented migration serializing and improved error

  • Loading branch information...
commit 6bbb82001455efb39a57c8ccfe09ff027633eced 1 parent 34263c6
Andrew Godwin authored January 19, 2014
6  django/db/migrations/writer.py
@@ -2,6 +2,7 @@
2 2
 
3 3
 import datetime
4 4
 import inspect
  5
+import decimal
5 6
 from importlib import import_module
6 7
 import os
7 8
 import types
@@ -221,6 +222,9 @@ def serialize(cls, value):
221 222
         # Promise
222 223
         elif isinstance(value, Promise):
223 224
             return repr(force_text(value)), set()
  225
+        # Decimal
  226
+        elif isinstance(value, decimal.Decimal):
  227
+            return repr(value), set(["from decimal import Decimal"])
224 228
         # Django fields
225 229
         elif isinstance(value, models.Field):
226 230
             attr_name, path, args, kwargs = value.deconstruct()
@@ -255,7 +259,7 @@ def serialize(cls, value):
255 259
                 return "%s.%s" % (module, value.__name__), set(["import %s" % module])
256 260
         # Uh oh.
257 261
         else:
258  
-            raise ValueError("Cannot serialize: %r" % value)
  262
+            raise ValueError("Cannot serialize: %r\nThere are some values Django cannot serialize into migration files.\nFor more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing" % value)
259 263
 
260 264
 
261 265
 MIGRATION_TEMPLATE = """\
54  docs/topics/migrations.txt
@@ -281,6 +281,7 @@ Note that this only works given two things:
281 281
   that your database doesn't match your models, you'll just get errors when
282 282
   migrations try to modify those tables.
283 283
 
  284
+
284 285
 .. _historical-models:
285 286
 
286 287
 Historical models
@@ -302,3 +303,56 @@ so you must always keep base classes around for as long as there is a migration
302 303
 that contains a reference to them. On the plus side, methods and managers
303 304
 from these base classes inherit normally, so if you absolutely need access
304 305
 to these you can opt to move them into a superclass.
  306
+
  307
+
  308
+.. _migration-serializing:
  309
+
  310
+Serializing values
  311
+------------------
  312
+
  313
+Migrations are just Python files containing the old definitions of your models
  314
+- thus, to write them, Django must take the current state of your models and
  315
+serialize them out into a file.
  316
+
  317
+While Django can serialize most things, there are some things that we just
  318
+can't serialize out into a valid Python representation - there's no Python
  319
+standard for how a value can be turned back into code (``repr()`` only works
  320
+for basic values, and doesn't specify import paths).
  321
+
  322
+Django can serialize the following:
  323
+
  324
+- ``int``, ``long``, ``float``, ``bool``, ``str``, ``unicode``, ``bytes``, ``None``
  325
+- ``list``, ``set``, ``tuple``, ``dict``
  326
+- ``datetime.date`` and ``datetime.datetime`` instances
  327
+- ``decimal.Decimal`` instances
  328
+- Any Django field
  329
+- Any function or method reference (e.g. ``datetime.datetime.today``)
  330
+- Any class reference
  331
+- Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
  332
+
  333
+Django cannot serialize:
  334
+
  335
+- Arbitrary class instances (e.g. ``MyClass(4.3, 5.7)``)
  336
+- Lambdas
  337
+
  338
+.. _custom-deconstruct-method:
  339
+
  340
+Adding a deconstruct() method
  341
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  342
+
  343
+You can let Django serialize your own custom class instances by giving the class
  344
+a ``deconstruct`` method. It takes no arguments, and should return a tuple
  345
+of 3 things: ``(path, args, kwargs)``.
  346
+
  347
+``path`` should be the Python path to the class, with the class name included as the
  348
+last part (for example, ``myapp.custom_things.MyClass``). If your class is not
  349
+available at the top level of a module it is not serializable.
  350
+
  351
+``args`` should be a list of positional arguments to pass to your class'
  352
+``__init__`` method. Everything in this list should itself be serializable.
  353
+
  354
+``kwargs`` should be a dict of keyword arguments to pass to your class'
  355
+``__init__`` method. Every value should itself be serializable.
  356
+
  357
+Django will write out the value as an instatiation of your class with the
  358
+given arguments, similar to the way it writes out references to Django fields.

0 notes on commit 6bbb820

Please sign in to comment.
Something went wrong with that request. Please try again.