Models & DB
Models
Common field types
- CharField is used to define short-to-mid sized fixed-length strings. You must specify the max_length of the data to be stored.
- TextField is used for large arbitrary-length strings. You may specify a max_length for the field, but this is used only when the field is displayed in forms (it is not enforced at the database level).
- IntegerField is a field for storing integer (whole number) values, and for validating entered values as integers in forms.
- DateField and DateTimeField are used for storing/representing dates and date/time information (as Python datetime.date in and datetime.datetime objects, respectively). These fields can additionally declare the (mutually exclusive) parameters auto_now=True (to set the field to the current date every time the model is saved), auto_now_add (to only set the date when the model is first created) , and default (to set a default date that can be overridden by the user).
- EmailField is used to store and validate email addresses.
- FileField and ImageField are used to upload files and images respectively (the ImageField adds additional validation that the uploaded file is an image). These have parameters to define how and where the uploaded files are stored.
- AutoField is a special type of IntegerField that automatically increments. A primary key of this type is automatically added to your model if you don’t explicitly specify one.
- ForeignKey is used to specify a one-to-many relationship to another database model (e.g. a car has one manufacturer, but a manufacturer can make many cars). The "one" side of the relationship is the model that contains the "key" (models containing a "foreign key" referring to that "key", are on the "many" side of such a relationship).
- ManyToManyField is used to specify a many-to-many relationship (e.g. a book can have several genres, and each genre can contain several books). In our library app we will use these very similarly to ForeignKeys, but they can be used in more complicated ways to describe the relationships between groups. These have the parameter on_delete to define what happens when the associated record is deleted (e.g. a value of models.SET_NULL would set the value to NULL).
Common field arguments
- help_text : Provides a text label for HTML forms (e.g. in the admin site), as described above.
- verbose_name: A human-readable name for the field used in field labels. If not specified, Django will infer the default verbose name from the field name.
- default: The default value for the field. This can be a value or a callable object, in which case the object will be called every time a new record is created.
- null: If True, Django will store blank values as NULL in the database for fields where this is appropriate (a CharField will instead store an empty string). The default is False.
- blank: If True, the field is allowed to be blank in your forms. The default is False, which means that Django's form validation will force you to enter a value. This is often used with null=True , because if you're going to allow blank values, you also want the database to be able to represent them appropriately.
- choices: A group of choices for this field. If this is provided, the default corresponding form widget will be a select box with these choices instead of the standard text field.
- primary_key: If True, sets the current field as the primary key for the model (A primary key is a special database column designated to uniquely identify all the different table records). If no field is specified as the primary key then Django will automatically add a field for this purpose.
Reference
Metadata
You can declare model-level metadata for your Model by declaring class Meta, as shown.
Info
ordering will change query default order
verbose_name will change display in admin panel
Abstract base class
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 abstract=True
in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.
Proxy models
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.
You could also use a proxy model to define a different default ordering on a model. You might not always want to order the Person model, but regularly order by the last_name attribute when you use the proxy:
Reference
Methods
Minimally, in every model you should define the standard Python class method __str__() to return a human-readable string for each object
Another common method to include in Django models is get_absolute_url(), which returns a URL for displaying individual model records on the website (if you define this method then Django will automatically add a "View on Site" button to the model's record editing screens in the Admin site). A typical pattern for get_absolute_url() is shown below.
Note
Assuming you will use URLs like /myapplication/mymodelname/2 to display individual records for your model (where "2" is the id for a particular record), you will need to create a URL mapper to pass the response and id to a "model detail view" (which will do the work required to display the record).
The reverse() function above is able to "reverse" your url mapper (in the above case named 'model-detail-view') in order to create a URL of the right format.
Queries
Throughout this guide (and in the reference), we’ll refer to the following models, which comprise a Weblog application:
Create/Update/Delete
Info
Create a new blog object
The save method has no return value
Info
- The update() method is applied instantly and returns the number of rows matched by the query
- Calls to update can also use F expressions to update one field based on the value of another field in the model
Warning
If you try to add an author to an entry you just created, you need to first save this entry and then use 'add'.
Info
The delete method immediately deletes the object and returns the number of objects deleted and a dictionary with the number of deletions per object type.
Although there is no built-in method for copying model instances, it is possible to easily create new instance with all fields’ values copied. In the simplest case, you can set pk to None. Using our blog example:
Things get more complicated if you use inheritance. Consider a subclass of Blog:
Due to how inheritance works, you have to set both pk and id to None:
This process doesn’t copy relations that aren’t part of the model’s database table. For example, Entry has a ManyToManyField to Author. After duplicating an entry, you must set the many-to-many relations for the new entry:
Use bulk methods to reduce the number of SQL statements.
Retrieving objects in Querysets
Info
The all() method returns a QuerySet of all the objects in the database.
Info
Filter/Exclude returns a new QuerySet
If you know there is only one object that matches your query, you can use the get() method on a Manager which returns the object
Warning
Returns an object !
Django will complain if more than one item matches the get() query. (MultipleObjectsReturned error)
Django will complain if there are no results that match the query (DoesNotExist exception)
QuerySubsets
Get only a part of the queryset
Info
Returns the first object of the queryset
Field lookups
Basic lookups keyword arguments take the form field__lookuptype=value
Assuming we have :
Django offers a powerful and intuitive way to “follow” relationships in lookups, taking care of the SQL JOINs for you automatically, behind the scenes
Reference
Querying JSONField
To query based on a given dictionary key, use that key as the lookup name:
JSON field lookup
The returned objects are those where the given dict of key-value pairs are all contained in the top-level of the field
The objects returned will be those where the key-value pairs on the object are a subset of those in the value passed
Warning
Not supported on Oracle and SQLite
Returns objects where the given key is in the top-level of the data
Reference
Aggregate / Annotate
Throughout this guide, we’ll refer to the following models. These models are used to track the inventory for a series of online bookstores:
Here’s how to do common aggregate queries, assuming the models above
Common Annotate queries (per object summaries)
If in doubt, inspect the SQL query!
In order to understand what happens in your query, consider inspecting the query property of your QuerySet
Reference
Custom managers
You can use a custom Manager in a particular model by extending the base Manager class and instantiating your custom Manager in your model.
There are two reasons you might want to customize a Manager: to add extra Manager methods, and/or to modify the initial QuerySet the Manager returns.
Adding extra manager methods
Adding extra Manager methods is the preferred way to add “table-level” functionality to your models. (For “row-level” functionality – i.e., functions that act on a single instance of a model object – use Model methods, not custom Manager methods.)
For example, this custom Manager adds a method with_counts():
With this example, you’d use OpinionPoll.objects.with_counts() to get a QuerySet of OpinionPoll objects with the extra num_responses attribute attached.
Modifying a manager’s initial QuerySet
You can override a Manager’s base QuerySet by overriding the Manager.get_queryset() method. get_queryset() should return a QuerySet with the properties you require.