Django model syntax change

As of [549], Django's model syntax has changed. If you're using models that use old (pre-[549]) syntax, you'll need to convert them according to the these instructions.

See the screencast.

What changed

  • Fields are now attributes of the model class, rather than members of a fields list.
  • Meta information (anything that's NOT a field, such as ordering, admin, unique_together, etc.) now goes in an inner class, called META (note the all caps). This class doesn't have a parent class.
  • To manually specify a field's database column name, use db_column as an argument to *Field().
  • When instantiating an object, you can now pass in many-to-one related object instances. Example: p = polls.get_object(pk=1); choice = choices.Choice(poll=p, choice="Hello", votes=0). Note that choices.choice(, ...) still works.
  • Each field is required to have an explicit name -- even ForeignKeys, ManyToManyFields and OneToOneFields. This solves the problem of "How do I refer to my field from within admin.fields?"
  • rel_name is no longer used for ForeignKeys. If your model has more than one ForeignKey to the same foreign model, differentiate the fields using the field name, not rel_name. See Relating a model to another model more than once for an example.
  • rel_name is no longer used for ManyToManyFields. If your model has more than one ManyToManyField to the same foreign model, differentiate the fields using the field name, not rel_name. Also, give both of the ManyToManyFields a singular attribute, which defines the name of the related object in singular format. (This is an obscure case, but it's included here for completeness.)
  • Syntax for subclassing models (add_fields, remove_fields) has changed. See tests/testapp/models/ for examples.


Old syntax example

class Foo(meta.Model):
    fields = (
        meta.CharField('first_name', "The person's first name", maxlength=30),
        meta.CharField('last_name', maxlength=30),
    ordering = ('-bar_id',)
    admin = meta.Admin(
        fields = (
            (None, {'fields': ('first_name', 'last_name', 'bar_id', 'sites')}),

    def __repr__(self):
        return self.first_name

New syntax example

class Foo(meta.Model):
    first_name = meta.CharField("The person's first name", maxlength=30)
    last_name = meta.CharField(maxlength=30)
    bar = meta.ForeignKey(Bar)
    sites = meta.ManyToManyField(Sites)
    class META:
        ordering = ('-bar',)
        admin = meta.Admin(
            fields = (
                (None, {'fields': ('first_name', 'last_name', 'bar', 'sites')}),

    def __repr__(self):
        return self.first_name


  • bar and sites now have explicit names, and admin.fields was changed to use bar instead of bar_id.
  • ordering was also changed to use the explicit name bar instead of bar_id. bar_id isn't used anywhere anymore; always use the explicit field name as defined in the model.
  • "sites" is the explicit field name for the Sites many-to-many relationship. Previously, Django calculated this automatically by using the module_name of the related model by default, or rel_name if it was given.
  • The verbose_name is now an optional first argument to Fields. For ForeignKeys, ManyToManyFields and OneToOneFields, use a named argument: verbose_name="foo".
  • Don't forget to remove the commas after each Field, because they're class attributes instead of tuple elements now.
  • Custom methods (such as __repr__() here) still go at the class level. They haven't changed.

User-contributed notes:

  • module_constants no longer works, even in class META. Use import statements where needed instead.
  • When searching on a ForeignKey in get_list(), you no longer refer to field_id. So, for example, instead of the old call thingys.get_list(related_id__exact=x), you would now call thingys.get_list(related__id__exact=x).
Last modified 19 years ago Last modified on Aug 26, 2005, 1:51:55 PM
Note: See TracWiki for help on using the wiki.
Back to Top