一、django 查詢的方法
def detail(request,id):
#查詢一個對象
xxx = xxx.objects.filter(id=id).first()
#如果使用上邊的方法查詢,如果數據不存在會爆異常,如果想讓 程序不報錯,需加一個捕獲異常,如下:
try:
xxx = xxx.objects.get(id=id)
except xxx.DoesNotExist as e:
print(e)
return render(request,'app05/jianli.html',locals())
查詢集
當查詢結果是多個的時候,django-ORM會返回一個 查詢集(QuerySet) ,表示從數據庫中獲取對象的 集合 。
查詢集可以使用過濾器進行再次處理。
例如:查詢閱讀量大于20且評論數大于30的書
book = Book.objects.filter(b_read__gt=20)
book.filter(b_comment__gt=30)
<QuerySet [<Book:天龍八部>]>
查詢集的兩大特性
惰性查詢:創建查詢集不會訪問數據庫,直到調用數據時,才會訪問數據庫,調用數據的情況包括迭代、序列化、與if合用。
緩存:使用同一個查詢集,第一次使用時會發生數據庫的查詢,然后Django會把結果緩存下來,再次使用這個查詢集時會使用緩存的數據,減少了數據庫的查詢次數。
限制查詢集
可對查詢集進行取下標或切片操作,類似sql語句中的limit條件查詢,不支持負數索引
如:xxx.objects.all()[1:3]
查詢閱讀數大于20的結果,再取下標為1 的數據
book = Book.objects.filter(b_read__gt=20)
book[1]
<Book: 雪山飛狐>
二、django關聯
模型類關系
1.關系字段類型:多對多(ManyToManyField),一對多(ForeignKey),一對一(OneToOneField),自關聯
2.一對多關系
3.多對多關系
關聯查詢
1.通過對象進行關聯查詢
2.通過模型類進行查詢
3.自關聯:是一種特殊的一對多關系
表關系的建立
建立學院信息表、學生信息表、課程表、學生詳情表,
表關系如下:
1.學院信息表 《= 一對多 ForeignKeyField =》 學生信息表
2.學生信息表 《= 一對一 OneToOneField =》 學生詳細信息表
3.課程表 《= 多對多 ManyToManyField =》學生信息表
在model中建立以下幾個模型類:
models.py
from django.db import models
學院表
class Department(models.Model):
d_id = models.AutoField(primary_key=True)
d_name = models.CharField(max_length=30)
def __str__(self):
return "Department<d_id=%s,d_name=%s>"%(self.d_id,
self.d_name)
學生表
class Student(models.Model):
s_id = models.AutoField(primary_key=True)
s_name = models.CharField(max_length=30)
department = models.ForeignKey('Department',
null=True, #可以為空值
related_name='student', # 反向查詢用(就不_set了:d1.student_set.all() -》d1.student )
on_delete=models.CASCADE) # 外鍵,自動關聯表的主鍵 級聯刪除
def __str__(self):
return "Student<s_id=%s, s_name=%s,department_id=%s >"%(self.s_id,
self.s_name,
self.department_id)
學生選課表
class Course(models.Model):
c_id = models.AutoField(primary_key=True)
c_name= models.CharField(max_length=30)
student = models.ManyToManyField('Student',
related_name='course',
) # 多對多 生成第三張關系表
def __str__(self):
return "Course<c_id=%s,c_name=%s,student=%s>"%(self.c_id,self.c_name,self.student)
學生詳情表
class Stu_detail(models.Model):
s_id = models.OneToOneField('Student',on_delete=models.CASCADE) # 一對一, 級聯刪除
s_age = models.IntegerField()
gender = models.BooleanField(default=1)
city = models.CharField(max_length=30)
def __str__(self):
return"s_id=%s,s_age=%s,s_gender=%s"(self.s_id,self.s_age,self.gender)
一對多表關系數據的添加:
往數據表student中添加數據的第一種方式:
s1 = Student(s_name='xiaoming',department_id=1)
s1.save()
1
2
往數據表student中添加數據的第二種方式:
先在Department里面創建一條數據d1再進行操作
1.s2 = Student(s_name='小紅')
2.s2.department_id=d1
3.s2.save()
表關聯對象的訪問:
s1.department
屬性取值,會拿到的=d1
通過管理器反向訪問
d1.student_set.all()
在Foreignkey里面設置related_name='student',這樣就可以直接用名字而不是_set的形式了
d1.student.all()
這個是實例對象
s1.departmnet
下面3個是管理器
d1.student
s1.course
c1.student
處理關聯對象的一些方法:
# 一對多,多的那頭就有這個管理器,就有以下方法
# 管理器才能用add,create,clear,remove方法
d1 = Department.objects.get(d_id=1)
s1 = Student.objects.get(s_id=1)
c1 = Course.objects.get(c_id=1)
# print(d1,s1,c1)
print(d1.student.all()) # 查詢到學院的所有學生, 通過一對多關系,管理器.all()
print(s1.department) # 模型類里面的屬性,直接訪問
print(c1.student) # 管理器 多對多
print(c1.student.all()) # 報名這個課程的學生
# print(s1.course_set.all()) # 學生報了哪些課, 反向查詢,可以用related_name去改
print(s1.course.all()) # 學生報了哪些課, 反向查詢用related_name 管理器
create(**kwargs) 添加不存在的數據 ,將數據直接存入數據庫
創建一個新的對象,將它保存并放在關聯的對象集返回新創建的對象
s1.course.create(c_name='C語言程序設計') # 會同時向兩個表格添加數據
d1.student.create(s_name='小帥') # 給d1學院添加一個學生(之前不存在數據庫中)
多表查詢—-跨關聯關系的查詢:
查詢學院名字為‘計算機學院’的學生的信息
Student.objects.filter(department__d_name='計算機學院')
查詢學生名字中包含 '小' 的學生的學院信息
Department.objects.filter(student__s_name__contains='小')
查詢學號為1的學生所有的課程
Course.objects.filter(student__s_id=1)
查詢報了課程1的所有的學生
Student.objects.filter(course__c_id=1)
查詢報了'python'課程的的學生的所屬學院的信息
Department.objects.filter(student__course__c_name='python')
django模型類拓展
1.模型實例方法
str()對象轉換為字符串時調用
save()保存模型對象到數據庫,orm框架會轉換為對應的insert或update語句
delete()刪除模型對象,orm框架會轉換為對應的delete語句
模型類的屬性
objects:管理器,是models.Manager類型的對象,用于和數據庫進行交互
管理器Manager
自定義管理器類主要用于:
1.修改原始查詢集,重寫all()方法
2.向管理器類添加新方法,如向數據庫插入數據
- 修改原始查詢集,重寫all()方法
如:
打開booktest/models.py文件,定義類BookInfoManager
圖書管理器class BookInfoManager(models.Manager): def all(self): #默認查詢未刪除的圖書信息
調用父類的成員語法為:super().方法名 return super().all().filter(isDelete=False)
在模型類BookInfo中定義管理器
class BookInfo(models.Model):
books = BookInfoManager()
- 在管理器類中定義創建對象的方法
如:
打開booktest/models.py文件,定義方法create。
class BookInfoManager(models.Manager):
... #創建模型類,接收參數為屬性賦值 def create_book(self, title, pub_date): #創建模型類對象self.model可以獲得模型類
book = self.model()
book.btitle = title
book.bpub_date = pub_date
book.bread=0
book.bcommet=0
book.isDelete = False # 將數據插入進數據表
book.save() return book
為模型類BookInfo定義管理器books語法如下
class BookInfo(models.Model):
books = BookInfoManager()
調用語法如下:
調用:book=BookInfo.books.create_book("abc",date(1980,1,1))
元選項
如:
from django.db import models
class Ox(models.Model):
horn_length = models.IntegerField()
class Meta:
ordering = ["horn_length"]
verbose_name_plural = "oxen"
常用元選項
db_table
該模型所用的數據表的名稱:
db_table = 'music_album'
ordering
對象默認的順序,獲取一個對象的列表時會按照這個字段排序:
它是一個字符串的列表或元組。每個字符串是一個字段名,前面帶有可選的“-”前綴表示倒序。前面沒有“-”的字段表示正序。使用"?"來表示隨機排序。
例如:按照pub_date字段的倒序排序,這樣寫:
ordering = ['-pub_date']
要按照pub_date字段的正序排序,這樣寫:
ordering = ['pub_date']
注意:排序并不是沒有任何代價的操作。你向ordering屬性添加的每個字段都會產生你數據庫的開銷。你添加的每個外鍵也會隱式包含它的默認順序。
verbose_name
對象的一個易于理解的名稱,為單數:
如果此項沒有設置,Django會把類名拆分開來作為自述名,比如CamelCase 會變成camel case,
verbose_name = "pizza"
verbose_name_plural
該對象復數形式的名稱:
如果此項沒有設置,Django 會使用verbose_name + 's'。
一般都是和verbose_name一起使用
verbose_name = "pizza"
verbose_name_plural = verbose_name