导航菜单

Models

Models¶

A model is the single, definitive source of information about your data. Itcontains the essential fields and behaviors of the data you’re storing.Generally, each model maps to a single database table.

The basics:

Each model is a Python class that subclassesdjango.db.models.Model.

Each attribute of the model represents a database field.

With all of this, Django gives you an automatically-generateddatabase-access API; see Making queries.

Quick example¶

This example model defines a Person, which has a first_name andlast_name:

from django.db import modelsclass Person(models.Model):first_name = models.CharField(max_length=30)last_name = models.CharField(max_length=30)

first_name and last_name are fields of the model. Each field isspecified as a class attribute, and each attribute maps to a database column.

The above Person model would create a database table like this:

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:

The name of the table, myapp_person, is automatically derived fromsome model metadata but can be overridden. See Table names for moredetails.

An id field is added automatically, but this behavior can beoverridden. See Automatic primary key fields.

The CREATE TABLE SQL in this example is formatted using PostgreSQLsyntax, but it’s worth noting Django uses SQL tailored to the databasebackend specified in your settings file.

Using models¶

Once you have defined your models, you need to tell Django you’re going to usethose models. Do this by editing your settings file and changing theINSTALLED_APPS setting to add the name of the module that containsyour models.py.

For example, if the models for your application live in the modulemyapp.models (the package structure that is created for anapplication by the manage.py startapp script),INSTALLED_APPS should read, in part:

INSTALLED_APPS = [# ..."myapp",# ...]

When you add new apps to INSTALLED_APPS, be sure to runmanage.py migrate, optionally making migrationsfor them first with manage.py makemigrations.

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 classattributes. Be careful not to choose field names that conflict with themodels API like clean, save, ordelete.

Example:

from django.db import modelsclass 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 appropriateField class. Django uses the field class types todetermine a few things:

The column type, which tells the database what kind of data to store (e.g.INTEGER, VARCHAR, TEXT).

The default HTML widget to use when rendering a formfield (e.g. , ).

The minimal validation requirements, used in Django’s admin and inautomatically-generated forms.

Django ships with dozens of built-in field types; you can find the complete listin the model field reference. You can easily writeyour own fields if Django’s built-in ones don’t do the trick; seeHow to create custom model fields.

Field options¶

Each field takes a certain set of field-specific arguments (documented in themodel field reference). For example,CharField (and its subclasses) require amax_length argument which specifies the sizeof the VARCHAR database field used to store the data.

There’s also a set of common arguments available to all field types. All areoptional. They’re fully explained in the reference, but here’s a quick summary of the most often-usedones:

null

If True, Django will store empty values as NULL in the database.Default is False.

blank

If True, the field is allowed to be blank. Default is False.

Note that this is different than null.null is purely database-related, whereasblank is validation-related. If a field hasblank=True, form validation willallow entry of an empty value. If a field has blank=False, the field will be required.

choices

A sequence of 2-value tuples, a mapping, anenumeration type, or a callable (thatexpects no arguments and returns any of the previous formats), to use aschoices for this field. If this is given, the default form widget will be aselect box instead of the standard text field and will limit choices to thechoices 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 choices changes.

The first element in each tuple is the value that will be stored in thedatabase. The second element is displayed by the field’s form widget.

Given a model instance, the display value for a field with choices canbe accessed using the get_FOO_display()method. For example:

from django.db import modelsclass 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 choices in a conciseway:

from django.db import modelsclass Runner(models.Model):MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")name = models.CharField(max_length=60)medal = models.CharField(blank=True, choices=MedalType, max_length=10)

Further examples are available in the model field reference.

Changed in Django 5.0:

Support for mappings and callables was added.

default

The default value for the field. This can be a value or a callableobject. If callable it will be called every time a new object iscreated.

db_default

The database-computed default value for the field. This can be a literalvalue or a database function.

If both db_default and Field.default are set, default willtake precedence when creating instances in Python code. db_default willstill be set at the database level and will be used when inserting rowsoutside of the ORM or when adding a new field in a migration.

help_text

Extra “help” text to be displayed with the form widget. It’s useful fordocumentation even if your field isn’t used on a form.

primary_key

If True, this field is the primary key for the model.

If you don’t specify primary_key=True forany fields in your model, Django will automatically add anIntegerField to hold the primary key, so you don’t need to setprimary_key=True on any of your fieldsunless you want to override the default primary-key behavior. For more,see Automatic primary key fields.

The primary key field is read-only. If you change the value of the primarykey on an existing object and then save it, a new object will be createdalongside the old one. For example:

from django.db import modelsclass 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)unique

If True, this field must be unique throughout the table.

Again, these are just short descriptions of the most common field options. Fulldetails 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 thetype specified per app in AppConfig.default_auto_field or globally in theDEFAULT_AUTO_FIELD setting. For example:

id = models.BigAutoField(primary_key=True)

If you’d like to specify a custom primary key, specifyprimary_key=True on one of your fields. If Djangosees you’ve explicitly set Field.primary_key, it won’t add the automaticid column.

Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).

Verbose field names¶

Each field type, except for ForeignKey,ManyToManyField andOneToOneField, takes an optional first positionalargument – a verbose name. If the verbose name isn’t given, Django willautomatically create it using the field’s attribute name, converting underscoresto spaces.

In this example, the verbose name is "person's first name":

first_name = models.CharField("person's first name", max_length=30)

In this example, the verbose name is "first name":

first_name = models.CharField(max_length=30)

ForeignKey,ManyToManyField andOneToOneField require the first argument to be amodel class, so use the verbose_name keyword argument:

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 theverbose_name. Django will automatically capitalize the firstletter where it needs to.

Relationships¶

Clearly, the power of relational databases lies in relating tables to eachother. Django offers ways to define the three most common types of databaserelationships: many-to-one, many-to-many and one-to-one.

Many-to-one relationships¶

To define a many-to-one relationship, use django.db.models.ForeignKey.You use it just like any other Field type: byincluding it as a class attribute of your model.

ForeignKey requires a positional argument: the classto which the model is related.

For example, if a Car model has a Manufacturer – that is, aManufacturer makes multiple cars but each Car only has oneManufacturer – use the following definitions:

from django.db import modelsclass Manufacturer(models.Model):# ...passclass Car(models.Model):manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)# ...

You can also create recursive relationships (anobject with a many-to-one relationship to itself) and relationships tomodels not yet defined; see the model fieldreference for details.

It’s suggested, but not required, that the name of aForeignKey field (manufacturer in the exampleabove) be the name of the model, lowercase. You can call the field whatever youwant. For example:

class Car(models.Model):company_that_makes_it = models.ForeignKey(Manufacturer,on_delete=models.CASCADE,)# ...

See also

ForeignKey fields accept a number of extraarguments which are explained in the model field reference. These options help define how the relationshipshould work; all are optional.

For details on accessing backwards-related objects, see theFollowing relationships backward example.

For sample code, see the Many-to-one relationship model example.

Many-to-many relationships¶

To define a many-to-many relationship, useManyToManyField. You use it just like any otherField type: by including it as a class attribute ofyour model.

ManyToManyField requires a positional argument: theclass to which the model is related.

For example, if a Pizza has multiple Topping objects – that is, aTopping can be on multiple pizzas and each Pizza has multiple toppings– here’s how you’d represent that:

from django.db import modelsclass Topping(models.Model):# ...passclass Pizza(models.Model):# ...toppings = models.ManyToManyField(Topping)

As with ForeignKey, you can also createrecursive relationships (an object with amany-to-many relationship to itself) and relationships to models not yetdefined.

It’s suggested, but not required, that the name of aManyToManyField (toppings in the example above)be a plural describing the set of related model objects.

It doesn’t matter which model has theManyToManyField, but you should only put it in oneof the models – not both.

Generally, ManyToManyField instances should go inthe object that’s going to be edited on a form. In the above example,toppings is in Pizza (rather than Topping having a pizzasManyToManyField ) because it’s more natural to thinkabout a pizza having toppings than a topping being on multiple pizzas. The wayit’s set up above, the Pizza form would let users select the toppings.

See also

See the Many-to-many relationship model example for a full example.

ManyToManyField fields also accept a number ofextra arguments which are explained in the model field reference. These options help define how the relationshipshould work; all are optional.

Extra fields on many-to-many relationships¶

When you’re only dealing with many-to-many relationships such as mixing andmatching pizzas and toppings, a standardManyToManyField is all you need. However, sometimesyou may need to associate data with the relationship between two models.

For example, consider the case of an application tracking the musical groupswhich musicians belong to. There is a many-to-many relationship between a personand the groups of which they are a member, so you could use aManyToManyField to represent this relationship.However, there is a lot of detail about the membership that you might want tocollect, such as the date at which the person joined the group.

For these situations, Django allows you to specify the model that will be usedto govern the many-to-many relationship. You can then put extra fields on theintermediate model. The intermediate model is associated with theManyToManyField using thethrough argument to point to the modelthat will act as an intermediary. For our musician example, the code would looksomething like this:

from django.db import modelsclass Person(models.Model):name = models.CharField(max_length=128)def __str__(self):return self.nameclass Group(models.Model):name = models.CharField(max_length=128)members = models.ManyToManyField(Person, through="Membership")def __str__(self):return self.nameclass 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 foreignkeys to the models that are involved in the many-to-many relationship. Thisexplicit declaration defines how the two models are related.

There are a few restrictions on the intermediate model:

Your intermediate model must contain one - and only one - foreign keyto the source model (this would be Group in our example), or you mustexplicitly specify the foreign keys Django should use for the relationshipusing ManyToManyField.through_fields.If you have more than one foreign key and through_fields is notspecified, a validation error will be raised. A similar restriction appliesto the foreign key to the target model (this would be Person in ourexample).

For a model which has a many-to-many relationship to itself through anintermediary model, two foreign keys to the same model are permitted, butthey will be treated as the two (different) sides of the many-to-manyrelationship. If there are more than two foreign keys though, youmust also specify through_fields as above, or a validation errorwill be raised.

Now that you have set up your ManyToManyField to useyour intermediary model (Membership, in this case), you’re ready to startcreating some many-to-many relationships. You do this by creating instances ofthe intermediate model:

>>> 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()>>> ringo.group_set.all()>>> m2 = Membership.objects.create(... person=paul,... group=beatles,... date_joined=date(1960, 8, 1),... invite_reason="Wanted to form a band.",... )>>> beatles.members.all()

You can also use add(),create(), orset() to createrelationships, as long as you specify through_defaults for any requiredfields:

>>> 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 enforceuniqueness on the (model1, model2) pair, allowing multiple values, theremove() call willremove all intermediate model instances:

>>> 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()>>> # This deletes both of the intermediate model instances for Ringo Starr>>> beatles.members.remove(ringo)>>> beatles.members.all()

The clear()method can be used to remove all many-to-many relationships for an instance:

>>> # Beatles have broken up>>> beatles.members.clear()>>> # Note that this deletes the intermediate model instances>>> Membership.objects.all()

Once you have established the many-to-many relationships, you can issuequeries. Just as with normal many-to-many relationships, you can query usingthe 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")

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)... )>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)>>> ringos_membership.date_joineddatetime.date(1962, 8, 16)>>> ringos_membership.invite_reason'Needed a new drummer.'

Another way to access the same information is by querying themany-to-many reverse relationship from aPerson object:

>>> ringos_membership = ringo.membership_set.get(group=beatles)>>> ringos_membership.date_joineddatetime.date(1962, 8, 16)>>> ringos_membership.invite_reason'Needed a new drummer.'One-to-one relationships¶

To define a one-to-one relationship, useOneToOneField. You use it just like any otherField type: by including it as a class attribute of your model.

This is most useful on the primary key of an object when that object “extends”another object in some way.

OneToOneField requires a positional argument: theclass to which the model is related.

For example, if you were building a database of “places”, you wouldbuild pretty standard stuff such as address, phone number, etc. in thedatabase. Then, if you wanted to build a database of restaurants ontop of the places, instead of repeating yourself and replicating thosefields in the Restaurant model, you could make Restaurant havea OneToOneField to Place (because arestaurant “is a” place; in fact, to handle this you’d typically useinheritance, which involves an implicitone-to-one relation).

As with ForeignKey, a recursive relationship can be defined and references to as-yetundefined models can be made.

See also

See the One-to-one relationship model example for a full example.

OneToOneField fields also accept an optionalparent_link argument.

OneToOneField classes used to automatically becomethe primary key on a model. This is no longer true (although you can manuallypass in the primary_key argument if you like).Thus, it’s now possible to have multiple fields of typeOneToOneField on a single model.

Models across files¶

It’s perfectly OK to relate a model to one from another app. To do this, importthe 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 modelsfrom geography.models import ZipCodeclass 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:

A field name cannot be a Python reserved word, because that would resultin a Python syntax error. For example:

class Example(models.Model):pass = models.IntegerField() # 'pass' is a reserved word!

A field name cannot contain more than one underscore in a row, due tothe way Django’s query lookup syntax works. For example:

class Example(models.Model):foo__bar = models.IntegerField() # 'foo__bar' has two underscores!

A field name cannot end with an underscore, for similar reasons.

These limitations can be worked around, though, because your field name doesn’tnecessarily have to match your database column name. See thedb_column option.

SQL reserved words, such as join, where or select, are allowed asmodel field names, because Django escapes all database table names and columnnames in every underlying SQL query. It uses the quoting syntax of yourparticular database engine.

Custom field types¶

If one of the existing model fields cannot be used to fit your purposes, or ifyou wish to take advantage of some less common database column types, you cancreate your own field class. Full coverage of creating your own fields isprovided in How to create custom model fields.

Meta options¶

Give your model metadata by using an inner class Meta, like so:

from django.db import modelsclass Ox(models.Model):horn_length = models.IntegerField()class Meta:ordering = ["horn_length"]verbose_name_plural = "oxen"

Model metadata is “anything that’s not a field”, such as ordering options(ordering), database table name (db_table), orhuman-readable singular and plural names (verbose_name andverbose_name_plural). None are required, and adding classMeta to a model is completely optional.

A complete list of all possible Meta options can be found in the modeloption reference.

Model attributes¶objects

The most important attribute of a model is theManager. It’s the interface through whichdatabase query operations are provided to Django models and is used toretrieve the instances from the database. If nocustom Manager is defined, the default name isobjects. Managers are only accessible viamodel classes, not the model instances.

Model methods¶

Define custom methods on a model to add custom “row-level” functionality to yourobjects. Whereas Manager methods are intended to do“table-wide” things, model methods should act on a particular model instance.

This is a valuable technique for keeping business logic in one place – themodel.

For example, this model has a few custom methods:

from django.db import modelsclass 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 datetimeif self.birth_date >> Place.objects.filter(name="Bob's Cafe")>>> Restaurant.objects.filter(name="Bob's Cafe")

If you have a Place that is also a Restaurant, you can get from thePlace object to the Restaurant object by using the lowercase version ofthe model name:

>>> p = Place.objects.get(id=12)# If p is a Restaurant object, this will give the child class:>>> p.restaurant

However, if p in the above example was not a Restaurant (it had beencreated directly as a Place object or was the parent of some other class),referring to p.restaurant would raise a Restaurant.DoesNotExistexception.

The automatically-created OneToOneField onRestaurant that links it to Place looks like this:

place_ptr = models.OneToOneField(Place,on_delete=models.CASCADE,parent_link=True,primary_key=True,)

You can override that field by declaring your ownOneToOneField with parent_link=True on Restaurant.

Meta and multi-table inheritance¶

In the multi-table inheritance situation, it doesn’t make sense for a childclass to inherit from its parent’s Meta class. All the Meta optionshave already been applied to the parent class and applying them again wouldnormally only lead to contradictory behavior (this is in contrast with theabstract base class case, where the base class doesn’t exist in its ownright).

So a child model does not have access to its parent’s Meta class. However, there are a few limited cases where the childinherits behavior from the parent: if the child does not specify anordering attribute or aget_latest_by attribute, it will inheritthese from its parent.

If the parent has an ordering and you don’t want the child to have any naturalordering, you can explicitly disable it:

class ChildModel(ParentModel):# ...class Meta:# Remove parent's ordering effectordering = []Inheritance and reverse relations¶

Because multi-table inheritance uses an implicitOneToOneField to link the child andthe parent, it’s possible to move from the parent down to the child,as in the above example. However, this uses up the name that is thedefault related_name value forForeignKey andManyToManyField relations. If youare putting those types of relations on a subclass of the parent model, youmust specify the related_nameattribute on each such field. If you forget, Django will raise a validationerror.

For example, using the above Place class again, let’s create anothersubclass with a ManyToManyField:

class Supplier(Place):customers = models.ManyToManyField(Place)

This results in the error:

Reverse query name for 'Supplier.customers' clashes with reverse queryname for 'Supplier.place_ptr'.HINT: Add or change a related_name argument to the definition for'Supplier.customers' or 'Supplier.place_ptr'.

Adding related_name to the customers field as follows would resolve theerror: models.ManyToManyField(Place, related_name='provider').

Specifying the parent link field¶

As mentioned, Django will automatically create aOneToOneField linking your childclass back to any non-abstract parent models. If you want to control thename of the attribute linking back to the parent, you can create yourown OneToOneField and setparent_link=Trueto indicate that your field is the link back to the parent class.

Proxy models¶

When using multi-table inheritance, a newdatabase table is created for each subclass of a model. This is usually thedesired behavior, since the subclass needs a place to store any additionaldata fields that are not present on the base class. Sometimes, however, youonly want to change the Python behavior of a model – perhaps to change thedefault manager, or add a new method.

This is what proxy model inheritance is for: creating a proxy for theoriginal model. You can create, delete and update instances of the proxy modeland 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 modelordering or the default manager in the proxy, without having to alter theoriginal.

Proxy models are declared like normal models. You tell Django that it’s aproxy model by setting the proxy attribute ofthe Meta class to True.

For example, suppose you want to add a method to the Person model. You can do it like this:

from django.db import modelsclass Person(models.Model):first_name = models.CharField(max_length=30)last_name = models.CharField(max_length=30)class MyPerson(Person):class Meta:proxy = Truedef do_something(self):# ...pass

The MyPerson class operates on the same database table as its parentPerson class. In particular, any new instances of Person will also beaccessible through MyPerson, and vice-versa:

>>> p = Person.objects.create(first_name="foobar")>>> MyPerson.objects.get(first_name="foobar")

You could also use a proxy model to define a different default ordering ona model. You might not always want to order the Person model, but regularlyorder by the last_name attribute when you use the proxy:

class OrderedPerson(Person):class Meta:ordering = ["last_name"]proxy = True

Now normal Person queries will be unorderedand OrderedPerson queries will be ordered by last_name.

Proxy models inherit Meta attributes in the same way as regularmodels.

QuerySets still return the model that was requested¶

There is no way to have Django return, say, a MyPerson object whenever youquery for Person objects. A queryset for Person objects will returnthose types of objects. The whole point of proxy objects is that code relyingon the original Person will use those and your own code can use theextensions you included (that no other code is relying on anyway). It is nota way to replace the Person (or any other) model everywhere with somethingof your own creation.

Base class restrictions¶

A proxy model must inherit from exactly one non-abstract model class. Youcan’t inherit from multiple non-abstract models as the proxy model doesn’tprovide any connection between the rows in the different database tables. Aproxy model can inherit from any number of abstract model classes, providingthey do not define any model fields. A proxy model may also inherit from anynumber of proxy models that share a common non-abstract parent class.

Proxy model managers¶

If you don’t specify any model managers on a proxy model, it inherits themanagers from its model parents. If you define a manager on the proxy model,it will become the default, although any managers defined on the parentclasses will still be available.

Continuing our example from above, you could change the default manager usedwhen you query the Person model like this:

from django.db import modelsclass NewManager(models.Manager):# ...passclass MyPerson(Person):objects = NewManager()class Meta:proxy = True

If you wanted to add a new manager to the Proxy, without replacing theexisting default, you can use the techniques described in the custommanager documentation: create a base classcontaining the new managers and inherit that after the primary base class:

# Create an abstract class for the new manager.class ExtraManagers(models.Model):secondary = NewManager()class Meta:abstract = Trueclass MyPerson(Person, ExtraManagers):class Meta:proxy = True

You probably won’t need to do this very often, but, when you do, it’spossible.

Differences between proxy inheritance and unmanaged models¶

Proxy model inheritance might look fairly similar to creating an unmanagedmodel, using the managed attribute on amodel’s Meta class.

With careful setting of Meta.db_table you could create an unmanaged model thatshadows an existing model and adds Python methods to it. However, that would bevery repetitive and fragile as you need to keep both copies synchronized if youmake any changes.

On the other hand, proxy models are intended to behave exactly like the modelthey are proxying for. They are always in sync with the parent model since theydirectly inherit its fields and managers.

The general rules are:

If you are mirroring an existing model or database table and don’t wantall the original database table columns, use Meta.managed=False.That option is normally useful for modeling database views and tablesnot under the control of Django.

If you are wanting to change the Python-only behavior of a model, butkeep all the same fields as in the original, use Meta.proxy=True.This sets things up so that the proxy model is an exact copy of thestorage structure of the original model when data is saved.

Multiple inheritance¶

Just as with Python’s subclassing, it’s possible for a Django model to inheritfrom multiple parent models. Keep in mind that normal Python name resolutionrules apply. The first base class that a particular name (e.g. Meta) appears in will be the one that is used; for example, thismeans that if multiple parents contain a Meta class,only the first one is going to be used, and all others will be ignored.

Generally, you won’t need to inherit from multiple parents. The main use-casewhere this is useful is for “mix-in” classes: adding a particular extrafield or method to every class that inherits the mix-in. Try to keep yourinheritance hierarchies as simple and straightforward as possible so that youwon’t have to struggle to work out where a particular piece of information iscoming from.

Note that inheriting from multiple models that have a common id primarykey field will raise an error. To properly use multiple inheritance, you canuse an explicit AutoField in the base models:

class Article(models.Model):article_id = models.AutoField(primary_key=True)...class Book(models.Model):book_id = models.AutoField(primary_key=True)...class BookReview(Book, Article):pass

Or use a common ancestor to hold the AutoField. Thisrequires using an explicit OneToOneField from eachparent model to the common ancestor to avoid a clash between the fields thatare automatically generated and inherited by the child:

class Piece(models.Model):passclass Article(Piece):article_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)...class Book(Piece):book_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)...class BookReview(Book, Article):passField name “hiding” is not permitted¶

In normal Python class inheritance, it is permissible for a child class tooverride any attribute from the parent class. In Django, this isn’t usuallypermitted for model fields. If a non-abstract model base class has a fieldcalled author, you can’t create another model field or definean attribute called author in any class that inherits from that base class.

This restriction doesn’t apply to model fields inherited from an abstractmodel. Such fields may be overridden with another field or value, or be removedby setting field_name = None.

Warning

Model managers are inherited from abstract base classes. Overriding aninherited field which is referenced by an inheritedManager may cause subtle bugs. See custommanagers and model inheritance.

Note

Some fields define extra attributes on the model, e.g. aForeignKey defines an extra attribute with_id appended to the field name, as well as related_name andrelated_query_name on the foreign model.

These extra attributes cannot be overridden unless the field that definesit is changed or removed so that it no longer defines the extra attribute.

Overriding fields in a parent model leads to difficulties in areas such asinitializing new instances (specifying which field is being initialized inModel.__init__) and serialization. These are features which normal Pythonclass inheritance doesn’t have to deal with in quite the same way, so thedifference between Django model inheritance and Python class inheritance isn’tarbitrary.

This restriction only applies to attributes which areField instances. Normal Python attributescan be overridden if you wish. It also only applies to the name of theattribute as Python sees it: if you are manually specifying the databasecolumn name, you can have the same column name appearing in both a child andan ancestor model for multi-table inheritance (they are columns in twodifferent database tables).

Django will raise a FieldError if you overrideany model field in any ancestor model.

Note that because of the way fields are resolved during class definition, modelfields inherited from multiple abstract parent models are resolved in a strictdepth-first order. This contrasts with standard Python MRO, which is resolvedbreadth-first in cases of diamond shaped inheritance. This difference onlyaffects complex model hierarchies, which (as per the advice above) you shouldtry to avoid.

Organizing models in a package¶

The manage.py startapp command creates an applicationstructure that includes a models.py file. If you have many models,organizing them in separate files may be useful.

To do so, create a models package. Remove models.py and create amyapp/models/ directory with an __init__.py file and the files tostore your models. You must import the models in the __init__.py file.

For example, if you had organic.py and synthetic.py in the modelsdirectory:

myapp/models/__init__.py¶from .organic import Personfrom .synthetic import Robot

Explicitly importing each model rather than using from .models import *has the advantages of not cluttering the namespace, making code more readable,and keeping code analysis tools useful.

See also

The Models Reference

Covers all the model related APIs including model fields, relatedobjects, and QuerySet.

相关推荐: