Version 3 (modified by Adrian Holovaty, 14 years ago) (diff)

Some bug fixes and clarifications.

Django model syntax change

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

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.
  • 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.)


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')}),

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')}),


  • 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.
  • 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 list elements now.
Back to Top