Models¶A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table. Show
The basics:
Quick example¶This example model defines a from django.db import models class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
The above
CREATE TABLE myapp_person ( "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "first_name" varchar(30) NOT NULL, "last_name" varchar(30) NOT NULL ); Some technical notes:
Using models¶Once you have defined your models, you need to tell Django you’re going to use those models. Do this by editing your settings file and changing the For
example, if the models for your application live in the module INSTALLED_APPS = [ #... 'myapp', #... ] When you add new apps to
Fields¶The most important part of a model – and the only required part of a model – is the list of database fields it defines. Fields are specified by class attributes. Be careful not to choose field names that conflict with the models API like Example: from django.db import models class Musician(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) instrument = models.CharField(max_length=100) class Album(models.Model): artist = models.ForeignKey(Musician, on_delete=models.CASCADE) name = models.CharField(max_length=100) release_date = models.DateField() num_stars = models.IntegerField() Field types¶Each field in your model should be an instance of the appropriate
Django ships with dozens of built-in field types; you can find the complete list in the model field reference. You can easily write your own fields if Django’s built-in ones don’t do the trick; see How to create custom model fields. Field options¶Each field takes a certain set of field-specific arguments (documented in the model field reference). For example,
There’s also a set of common arguments available to all field types. All are optional. They’re fully explained in the reference, but here’s a quick summary of the most often-used ones: null If True , Django will store empty
values as NULL in the database. Default is False .blank If Note that this is different than
choices A sequence of 2-tuples to use as choices for this field. If this is given, the default form widget will be a select box instead of the standard text field and will limit choices to the choices given. A choices list looks like this: YEAR_IN_SCHOOL_CHOICES = [ ('FR', 'Freshman'), ('SO', 'Sophomore'), ('JR', 'Junior'), ('SR', 'Senior'), ('GR', 'Graduate'), ] Note A new migration is created each time the order of The first element in each tuple is the value that will be stored in the database. The second element is displayed by the field’s form widget. Given a model instance, the display value for a field with from django.db import models class Person(models.Model): SHIRT_SIZES = ( ('S', 'Small'), ('M', 'Medium'), ('L', 'Large'), ) name = models.CharField(max_length=60) shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES) >>> p = Person(name="Fred Flintstone", shirt_size="L") >>> p.save() >>> p.shirt_size 'L' >>> p.get_shirt_size_display() 'Large' You can also use enumeration
classes to define from django.db import models class Runner(models.Model): MedalType = models.TextChoices('MedalType', 'GOLD SILVER BRONZE') name = models.CharField(max_length=60) medal = models.CharField(blank=True, choices=MedalType.choices, max_length=10) Further examples are available in the model field reference. default The default value for the field. This can be a value or a callable
object. If callable it will be called every time a new object is created.help_text Extra “help” text to be displayed with the form widget. It’s useful for documentation even if your field isn’t used on a form.primary_key If If you don’t specify The primary key field is read-only. If you change the value of the primary key on an existing object and then save it, a new object will be created alongside the old one. For example: from django.db import models class Fruit(models.Model): name = models.CharField(max_length=100, primary_key=True) >>> fruit = Fruit.objects.create(name='Apple') >>> fruit.name = 'Pear' >>> fruit.save() >>> Fruit.objects.values_list('name', flat=True) <QuerySet ['Apple', 'Pear']> unique If True , this field must be unique throughout the table.Again, these are just short descriptions of the most common field options. Full details can be found in the common model field option reference. Automatic primary key fields¶By default, Django gives each model an auto-incrementing primary key with the type specified per app in
id = models.BigAutoField(primary_key=True) If you’d like to specify a custom primary key, specify
Each model requires exactly one field to
have Verbose field names¶Each field type, except for
In this example, the verbose name is first_name = models.CharField("person's first name", max_length=30) In this example, the
verbose name is first_name = models.CharField(max_length=30)
poll = models.ForeignKey( Poll, on_delete=models.CASCADE, verbose_name="the related poll", ) sites = models.ManyToManyField(Site, verbose_name="list of sites") place = models.OneToOneField( Place, on_delete=models.CASCADE, verbose_name="related place", ) The convention is not to capitalize the first letter of the
Relationships¶Clearly, the power of relational databases lies in relating tables to each other. Django offers ways to define the three most common types of database relationships: many-to-one, many-to-many and one-to-one. Many-to-one relationships¶To define a many-to-one relationship, use
For example, if a from django.db import models class Manufacturer(models.Model): # ... pass class Car(models.Model): manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE) # ... You can also create recursive relationships (an object with a many-to-one relationship to itself) and relationships to models not yet defined; see the model field reference for details. It’s suggested, but not required, that the name of a class Car(models.Model): company_that_makes_it = models.ForeignKey( Manufacturer, on_delete=models.CASCADE, ) # ... Many-to-many relationships¶To define a many-to-many relationship, use
For example, if a from django.db import models class Topping(models.Model): # ... pass class Pizza(models.Model): # ... toppings = models.ManyToManyField(Topping) As with It’s suggested, but not required, that the name of a It doesn’t matter which model has the Generally,
Extra fields on many-to-many relationships¶When you’re only dealing with many-to-many relationships such as mixing and matching pizzas and toppings, a standard For example, consider the case of an application tracking the musical groups which musicians belong to. There is a many-to-many relationship between a person and the groups of which they are a member, so you could use a For these situations, Django allows you to specify the model that will be used to govern the many-to-many relationship. You can then put extra fields on the intermediate model. The intermediate model is associated with the
from django.db import models class Person(models.Model): name = models.CharField(max_length=128) def __str__(self): return self.name class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') def __str__(self): return self.name class Membership(models.Model): person = models.ForeignKey(Person, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() invite_reason = models.CharField(max_length=64) When you set up the intermediary model, you explicitly specify foreign keys to the models that are involved in the many-to-many relationship. This explicit declaration defines how the two models are related. There are a few restrictions on the intermediate model:
Now that you have set up your
>>> ringo = Person.objects.create(name="Ringo Starr") >>> paul = Person.objects.create(name="Paul McCartney") >>> beatles = Group.objects.create(name="The Beatles") >>> m1 = Membership(person=ringo, group=beatles, ... date_joined=date(1962, 8, 16), ... invite_reason="Needed a new drummer.") >>> m1.save() >>> beatles.members.all() <QuerySet [<Person: Ringo Starr>]> >>> ringo.group_set.all() <QuerySet [<Group: The Beatles>]> >>> m2 = Membership.objects.create(person=paul, group=beatles, ... date_joined=date(1960, 8, 1), ... invite_reason="Wanted to form a band.") >>> beatles.members.all() <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]> You can also use
>>> beatles.members.add(john, through_defaults={'date_joined': date(1960, 8, 1)}) >>> beatles.members.create(name="George Harrison", through_defaults={'date_joined': date(1960, 8, 1)}) >>> beatles.members.set([john, paul, ringo, george], through_defaults={'date_joined': date(1960, 8, 1)}) You may prefer to create instances of the intermediate model directly. If the custom through table defined by the intermediate model does not enforce uniqueness on the >>> Membership.objects.create(person=ringo, group=beatles, ... date_joined=date(1968, 9, 4), ... invite_reason="You've been gone for a month and we miss you.") >>> beatles.members.all() <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]> >>> # This deletes both of the intermediate model instances for Ringo Starr >>> beatles.members.remove(ringo) >>> beatles.members.all() <QuerySet [<Person: Paul McCartney>]> The
>>> # Beatles have broken up >>> beatles.members.clear() >>> # Note that this deletes the intermediate model instances >>> Membership.objects.all() <QuerySet []> Once you have established the many-to-many relationships, you can issue queries. Just as with normal many-to-many relationships, you can query using the attributes of the many-to-many-related model: # Find all the groups with a member whose name starts with 'Paul' >>> Group.objects.filter(members__name__startswith='Paul') <QuerySet [<Group: The Beatles>]> As you are using an intermediate model, you can also query on its attributes: # Find all the members of the Beatles that joined after 1 Jan 1961 >>> Person.objects.filter( ... group__name='The Beatles', ... membership__date_joined__gt=date(1961,1,1)) <QuerySet [<Person: Ringo Starr]> If you need to access a membership’s information you may do so by directly querying the >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo) >>> ringos_membership.date_joined datetime.date(1962, 8, 16) >>> ringos_membership.invite_reason 'Needed a new drummer.' Another way to access the same information is by querying the many-to-many reverse
relationship from a >>> ringos_membership = ringo.membership_set.get(group=beatles) >>> ringos_membership.date_joined datetime.date(1962, 8, 16) >>> ringos_membership.invite_reason 'Needed a new drummer.' One-to-one relationships¶To define a one-to-one relationship, use
This is most useful on the primary key of an object when that object “extends” another object in some way.
For example, if you were building a database of “places”, you would build pretty standard stuff such as address, phone number, etc. in the database. Then, if you wanted to build a database of restaurants on top of the places, instead of repeating yourself
and replicating those fields in the As with
Models across files¶It’s perfectly OK to relate a model to one from another app. To do this, import the related model at the top of the file where your model is defined. Then, refer to the other model class wherever needed. For example: from django.db import models from geography.models import ZipCode class Restaurant(models.Model): # ... zip_code = models.ForeignKey( ZipCode, on_delete=models.SET_NULL, blank=True, null=True, ) Field name restrictions¶Django places some restrictions on model field names:
These limitations can be worked around, though, because your field name doesn’t necessarily have to match your database column name.
See the SQL reserved words, such as Custom field types¶If one of the existing model fields cannot be used to fit your purposes, or if you wish to take advantage of some less common database column types, you can create your own field class. Full coverage of creating your own fields is provided in How to create custom model fields. Model attributes¶objects The most important attribute of a model is the
Manager . It’s the interface through which database query operations are provided to Django models and is used to retrieve the instances from the database. If no custom Manager is defined, the default name is
objects . Managers are only accessible via model classes, not the model instances.Model methods¶Define custom methods on a model to add custom “row-level”
functionality to your objects. Whereas This is a valuable technique for keeping business logic in one place – the model. For example, this model has a few custom methods: from django.db import models class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() def baby_boomer_status(self): "Returns the person's baby-boomer status." import datetime if self.birth_date < datetime.date(1945, 8, 1): return "Pre-boomer" elif self.birth_date < datetime.date(1965, 1, 1): return "Baby boomer" else: return "Post-boomer" @property def full_name(self): "Returns the person's full name." return '%s %s' % (self.first_name, self.last_name) The last method in this example is a property. The model instance reference has a complete list of methods automatically given to each model. You can override most of these – see overriding predefined model methods, below – but there are a couple that you’ll almost always want to define: __str__() A Python “magic method” that returns a string representation of any object. This is what Python and Django will use whenever a model instance needs to be coerced and displayed as a plain string. Most notably, this happens when you display an object in an interactive console or in the admin. You’ll always want to define this method; the default isn’t very helpful at all. get_absolute_url() This tells Django how to calculate the URL for an object. Django uses this in its admin interface, and any time it needs to figure out a URL for an object. Any object that has a URL that uniquely identifies it should define this method. Overriding predefined model methods¶There’s another set of model methods that encapsulate a bunch of database behavior that you’ll want to customize. In
particular you’ll often want to change the way You’re free to override these methods (and any other model method) to alter behavior. A classic
use-case for overriding the built-in methods is if you want something to happen whenever you save an object. For example (see from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def save(self, *args, **kwargs): do_something() super().save(*args, **kwargs) # Call the "real" save() method. do_something_else() You can also prevent saving: from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def save(self, *args, **kwargs): if self.name == "Yoko Ono's blog": return # Yoko shall never have her own blog! else: super().save(*args, **kwargs) # Call the "real" save() method. It’s important to remember to call the superclass method – that’s that It’s also important that you pass through the arguments that can be passed to the model method – that’s what the Executing custom SQL¶Another common pattern is writing custom SQL statements in model methods and module-level methods. For more details on using raw SQL, see the documentation on using raw SQL. Model inheritance¶Model inheritance in Django works almost identically to the way normal class inheritance works in Python, but the basics at the beginning of the page should still be followed.
That means the base class should subclass The only decision you have to make is whether you want the parent models to be models in their own right (with their own database tables), or if the parents are just holders of common information that will only be visible through the child models. There are three styles of inheritance that are possible in Django.
Abstract base classes¶Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put An example: from django.db import models class CommonInfo(models.Model): name = models.CharField(max_length=100) age = models.PositiveIntegerField() class Meta: abstract = True class Student(CommonInfo): home_group = models.CharField(max_length=5) The Fields
inherited from abstract base classes can be overridden with another field or value, or be removed with For many uses, this type of model inheritance will be exactly what you want. It provides a way to factor out common information at the Python level, while still only creating one database table per child model at the database level. Multi-table inheritance¶The second type of model inheritance supported by Django is when each model in the hierarchy is a model all by itself. Each model corresponds to its own database table and can be queried and created individually. The inheritance relationship introduces links between the child model and each of its parents (via an
automatically-created from django.db import models class Place(models.Model): name = models.CharField(max_length=50) address = models.CharField(max_length=80) class Restaurant(Place): serves_hot_dogs = models.BooleanField(default=False) serves_pizza = models.BooleanField(default=False) All of the fields of >>> Place.objects.filter(name="Bob's Cafe") >>> Restaurant.objects.filter(name="Bob's Cafe") If you have a >>> p = Place.objects.get(id=12) # If p is a Restaurant object, this will give the child class: >>> p.restaurant <Restaurant: ...> However, if The automatically-created
place_ptr = models.OneToOneField( Place, on_delete=models.CASCADE, parent_link=True, primary_key=True, ) You can override that field by declaring your own Inheritance and reverse relations¶Because multi-table inheritance uses an
implicit For example, using the above class Supplier(Place): customers = models.ManyToManyField(Place) This results in the error: Reverse query name for 'Supplier.customers' clashes with reverse query name for 'Supplier.place_ptr'. HINT: Add or change a related_name argument to the definition for 'Supplier.customers' or 'Supplier.place_ptr'. Adding Specifying the parent link field¶As mentioned, Django will automatically create a Proxy models¶When using multi-table inheritance, a new database table is created for each subclass of a model. This is usually the desired behavior, since the subclass needs a place to store any additional data fields that are not present on the base class. Sometimes, however, you only want to change the Python behavior of a model – perhaps to change the default manager, or add a new method. This is what proxy model inheritance is for: creating a proxy for the original model. You can create, delete and update instances of the proxy model and all the data will be saved as if you were using the original (non-proxied) model. The difference is that you can change things like the default model ordering or the default manager in the proxy, without having to alter the original. Proxy models are declared like normal models. You tell Django that it’s a proxy model by setting the For
example, suppose you want to add a method to the from django.db import models class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) class MyPerson(Person): class Meta: proxy = True def do_something(self): # ... pass The >>> p = Person.objects.create(first_name="foobar") >>> MyPerson.objects.get(first_name="foobar") <MyPerson: foobar> You could also use a proxy model to define a different default ordering on a model. You might not always want to order the class OrderedPerson(Person): class Meta: ordering = ["last_name"] proxy = True Now normal Proxy models inherit
|