In this chapter we'll build on the previous Django model concepts and learn about a Django model queries and managers. Next, you'll learn about the many SQL query variations supported by Django models, including: Finally, you'll learn how to create and configure custom model managers in Django models.
CRUD single records in Django models Working with single records is one of the most common tasks you'll do with Django models.
Next, I'll structure the following sections into the classical web application CRUD operations and describe the various techniques for each case so you can get a better grasp of what to use under different circumstances.
Note that although the following sections concentrate on the actual CRUD operation and its behaviors, sometimes I'll inevitably introduce more advanced query concepts in the examples e. Create a single record with save or create To create a single record on a Django model, you just need to make an instance of a model and invoke the save method on it.
Listing illustrates the process to create a single record for a model called Store. Tip Consult the book's accompanying source code to run the exercises, in order to reduce typing and automatically access test data. Create a single record with model save method Import Django model class from coffeehouse. Once the instance is ready, call the save method on it to create the record in the database.
There are two important behaviors to be aware of when you invoke save method: By default, all Django models are assigned an auto-incrementing primary key named id, created when you initiate a model's database table -- see the previous chapter section on 'Django models and the migrations workflow' for more details. This means the database assigns an id value to a record -- unless you explicitly provide an id value to the instance -- that gets passed back to the reference.
The creation of a record is rejected if it violates any database or Django validation rule created by the Django model. This means that if a new instance doesn't comply with any of these validation rules, save generates an error. See the previous chapter section on 'Django models data types' for more details on rule validation. These are the two most important points when you use the save method to create a record. For the full set of options and subtleties associated with a Django model save method, see the previous chapter table and the section on 'Model methods'.
The create method offers a shorter route alternative to create a record. Listing illustrates the equivalent record creation in listing using the create method. Create a single record with create method Import Django model class from coffeehouse. The create method accepts arguments that represent the model instance field values. The execution of create returns an object reference to the created record including an id value just like the save method.
Behind the scenes, the create method actually uses the same save method, but it uses the model manager to allow the creation of a record in a single line. Listing illustrates a basic example of the get Django model method. Listing Read model record with get method Import Django model class from coffeehouse.
Once the record is assigned to a variable, you can access its contents or attributes using Python's dotted notation. In addition, Django also offerrs field lookup to create finer single record queries e. See the later section in the chapter on queries classified by SQL keyword.
It's that simple to use a Django model's get method. However, the get method has some behaviors you should be aware of: With get the query has to match one and only one record. If there are multiple matching records you will get a MultipleObjectsReturned error. This means there's no caching on Django's part for identical or multiple calls.
Knowing these get limitations, let's explore how to tackle the first scenario that involves a record that doesn't exist. A common occurrence when attempting to read a single record that doesn't exist, is to get it and if it doesn't exist just create it. True if created, False if read.
DoesNotExist which inherits from django. Now let's take a look at the second get limitation which involves getting multiple records on a query. By design, the get method throws a MultipleObjectsReturned error if more than one record matches a query.
This behavior is an actual feature, because there are circumstances when you want to ensure a query only returns one record and be informed otherwise e. If there's a possibility for a query to return one or multiple records, then you'll need to forgo the use of get method and use either a model manager's filter or exclude methods. Both the filter or exclude methods produce a multi-record data structure called a QuerySet, which can be reduced to a single record with an additional QuerySet method e.
Since a Django model's filter and exclude methods are designed for multiple record queries, these methods along with QuerySet behaviors are described in detail in the later section on CRUD operations for multiple records. Additional QuerySet methods like first are also described in the later section on model queries classified by SQL keyword.
Listing illustrates this process. Update model record with the save method Import Django model class from coffeehouse. Or the other alternative is to use save without any argument, in which case Django updates all fields. If you don't yet have a reference to the record to update, it's slightly inefficient to first get it i. In addition, doing the update process in separate steps can lead to race conditions. For example, if another user fetches the same data at the same time and also does an update, you'll both race to save it, but whose update is definitive and whose is overwritten?
Because no party is aware the other is working on the same data, you need a way to indicate -- technically known as lock or isolate -- the data to avoid race conditions. For such cases you can use the update method -- part of a model's default objects model manager -- which performs an update in a single operation and guarantees there are no race conditions.
Update model record with the update method from coffeehouse. For the moment, don't worry about Django F expressions -- they're described later on for more elaborate queries -- just realize Django F expressions allow you to reference model fields within a query -- as an SQL expression -- which is necessary in this case to perform the update in a single operation.
Caution The update method can update a field across multiple records if you're not careful. The update method is preceded by the objects. Notice in listing the query uses the id field to define the query, ensuring that only a single record matches the query, because id is the table's primary key.
If the query definition in objects. This method is helpful in cases where you want to perform an update and aren't sure if the record exists yet.
Delete a single record with delete If you already have a reference to a record, deleting it is as simple as invoking the delete method on it. Delete model record with the delete method Import Django model class from coffeehouse. For such cases you can use the delete method and append it to a query so everything is done in a single operation.
Delete model record with the delete method on query from coffeehouse. Menu type was deleted. Store -- in this case multiple records are deleted because stores. Caution The delete method can delete multiple records if you're not careful. The delete method is preceded by the objects. Notice in listing the query uses an id field to define the query, ensuring that only a single record matches the query, because id is a table's primary key.