ORM query and SQL statement
Multi-table operation
Create a model
Example: Let's assume the following concepts, fields and relationships
Author Model: An author has name and age.
Author detailed model: put the author's details in the details table, including birthday, mobile phone number, home address and other information. There is a one-to-one relationship between the author details model and the author model.
Publisher Model: Publisher has name, city and email.
Book model: Books have a title and a publication date. A book may have multiple authors, and an author can also write multiple books, so the relationship between authors and books is a many-to-many relationship (many-to-many) ; A book should only be published by one publisher, so publishers and books are one-to-many.
The model is built as follows:
from django.db import models # Create your models here. class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() # Establish a one-to-one relationship with AuthorDetail authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # Establish a one-to-many relationship with Publish, and the foreign key field is established on the many side publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # Establish a many-to-many relationship with the Author table, ManyToManyField can be built in either of the two models, and a third table can be created automatically authors=models.ManyToManyField(to='Author',)
The generated table is as follows:
Precautions:
- The name of the table
myapp_modelName
, which is automatically generated based on the metadata in the model, can also be overwritten with another name id
Fields are added automatically- For foreign key fields, Django will add "_id" to the field name to create the column name in the database
- The SQL statement in this example
CREATE TABLE
uses the PostgreSQL syntax format. It should be noted that Django will use the corresponding SQL statement according to the database type specified in the settings. - After defining your models, you need to tell Django to _use_ those models. All you have to do is to modify the INSTALL_APPSZ setting in the configuration file and add
models.py
the name of the application in it. - The foreign key field ForeignKey has a null=True setting (which allows foreign keys to accept the null value NULL), and you can assign it the null value None.
Add table record
Before the operation, simply enter some data:
publish table:
author table:
authordetail表:
one-to-many
Way 1: publish_obj=Publish.objects.get(nid=1) book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish=publish_obj) Method 2: book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish_id=1)
Core: What is book_obj.publish and book_obj.publish_id?
many-to-many
# Currently generated book object book_obj=Book.objects.create(title="追风筝的人",price=200,publishDate="2012-11-12",publish_id=1) # Bind the author object for the book yuan=Author.objects.filter(name="yuan").first() # The record whose primary key is 2 in the Author table egon=Author.objects.filter(name="alex").first() # Records whose primary key is 1 in the Author table # Bind a many-to-many relationship, that is, add a record to the relational table book_authors book_obj.authors.add(yuan,egon) # Add some specific model objects to the associated object collection. ======= book_obj.authors.add(*[])
The database table records are generated as follows:
book table
book_authors表
Core: what is book_obj.authors.all()?
Other common APIs for many-to-many relationships:
book_obj.authors.remove() # Remove a specific object from the associated object collection. ====== book_obj.authors.remove(* []) book_obj.authors.clear() #Clear the associated object collection book_obj.authors.set () #Empty and then set
RelatedManager
Object-based cross-table query
One-to-many query (Publish and Book)
Forward query (by field: publish):
# Query the city where the publisher of the book whose primary key is 1 book_obj=Book.objects.filter(pk=1).first() # book_obj.publish is the publisher object associated with the book object whose primary key is 1 print(book_obj.publish.city)
Reverse query (by table name: book_set):
publish =Publish.objects.get (name= " Apple Publishing " ) #publish.book_set.all() : A collection of all book objects associated with Apple Publishing book_list=publish.book_set.all() for book_obj in book_list: print(book_obj.title)
One-to-one query (Author and AuthorDetail)
Forward query (by field: authorDetail):
egon=Author.objects.filter(name="egon").first() print(egon.authorDetail.telephone)
Reverse query (by table name: author):
# Query the names of all authors whose addresses are in Beijing authorDetail_list=AuthorDetail.objects.filter(addr="beijing") for obj in authorDetail_list: print(obj.author.name)
Many-to-many query (Author and Book)
Forward query (by field: authors):
# The names and mobile phone numbers of all authors of Jin Ping Mei book_obj=Book.objects.filter(title="金瓶眉").first() authors=book_obj.authors.all() for author_obj in authors: print(author_obj.name,author_obj.authorDetail.telephone)
Reverse query (by table name: book_set):
# Query the names of all books published by egon author_obj=Author.objects.get(name="egon") book_list = author_obj.book_set.all() #All books related to egon authors for book_obj in book_list: print(book_obj.title)
Notice:
You can override the name of FOO_set by setting the value of related_name in the definitions of ForeignKey() and ManyToManyField. For example, if you make the following changes in the Article model:
publish = ForeignKey(Book, related_name='bookList')
Then we will see this next:
# Query all books published by People's Publishing House publish =Publish.objects.get ( name= " People's Publishing House " ) book_list =publish.bookList.all() # A collection of all book objects associated with People's Publishing House
Cross-table query based on double underscore
Django also provides an intuitive and efficient way to express relationships in lookups, and it can automatically confirm SQL JOIN relationships. To do a cross-relational query, use two underscores to link the names of the associated fields between models until you finally link to the model you want.
Key points: Forward query by field, reverse query by table name.
one-to-many query
# Exercise 1: Query the names and prices of all books published by Apple Press (one-to-many) # Forward query by field: publish queryResult=Book.objects .filter(publish__name = " Apple Publishing " ) .values_list("title","price") # Reverse query by table name: book queryResult=Publish.objects .filter(name = " Apple Press " ) .values_list("book__title","book__price")
Many-to-many query
# Exercise 2: Query the names of all books published by alex (many-to-many) # Forward query by field:authors: queryResult=Book.objects .filter(authors__name="yuan") .values_list("title") # Reverse query by table name: book queryResult=Author.objects .filter(name="yuan") .values_list("book__title","book__price") Mixed use
# Exercise 3: Query the names of all books published by People's Publishing House and the name of the author # Forward query queryResult=Book.objects .filter(publish__name = " People's Publishing House " ) .values_list("title","authors__name") # reverse lookup queryResult=Publish.objects .filter(name = " People's Publishing House " ) .values_list("book__title","book__authors__age","book__authors__name") # Exercise 4: All book names and publisher names published by authors whose phone numbers start with 151 queryResult=Book.objects .filter(authors__authorDetail__telephone__regex="151") .values_list("title","publish__name")
Notice:
When doing a reverse query, if related_name is defined, replace the table name with related_name, for example:
publish = ForeignKey(Blog, related_name='bookList')
Exercise 1: Query the names and prices of all books published by People's Publishing House (one-to-many)
# The reverse query is no longer by table name: book, but related_name: bookList queryResult=Publish.objects .filter(name = " People's Publishing House " ) .values_list("bookList__title","bookList__price")