2.order_by asc desc
from django.db.models.function import Lower
res = Student.objects.order_by(Lower('name').desc())
-
表關系的創建
-
-
OneToMany grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)
-
ManyToMany
-
class Cousrse(models.Model):
-
name = models.CharField('課程名稱',max_length=20)
-
students = models.ManyToMany('Student') 自動創建第三張表.
-
-
關聯表的數據操作
-
OneToMany
-
正向 :一個模型如果定義了一個外鍵字段,通過這個模型操作外鍵 增刪改查
-
反向 增刪改查
-Many-to-Many 指定了中間表,add,remove,set 都不能用,必須用中間表 -One-to-One
-
跨表查詢
1.實現課堂上的5個關聯表的關系 2.練習課堂上的案例
關系表中的數據操作:
進入項目目錄的IDLE:
為了能方便學習,我們進入項目的idle中去執行我們的操作,
通過python manage.py shell 就能進入當前目錄下的IDLE
1.進入IDLE
2.查看當前的目錄路徑
3.導入我們項目中的模型類
關系表的數據操作:
1.先往數據表department中添加數據.
2.查看數據表student的表結構.
department_id字段就是外鍵關聯的department表中的d_id字段
一對多表關系數據的添加:
3.往數據表student中添加數據的第一種方式
s = Students()
In [6]: s.name = '石麒詳'
In [7]: g1 = Grade.objects.first()
In [8]: g1 Out[8]: <Grade: Grade object (1)>
In [10]: s.grade = g1
In [11]: s.grade Out[11]: <Grade: Grade object (1)>
In [13]: s.save()
In [14]: s.grade Out[14]: <Grade: Grade object (1)>
4.往數據表student中添加數據的第二種方式
s1 = Student(name='二')
g2 = Grade.objects.last()
se.grade_id = g2.id
s2.save
這兩種方式的效果是一樣的.
1.第一種方式就是跟之前的一樣,用傳參的方法添加,需要注意的是外鍵的值必須是關聯表中已經存在的值.
2.第二種方式是用的屬性賦值的方式,因為我們在模型類有定義了一個department的屬性,而這個屬性的對象的類型必須是department表的類實例對象
刪除:s2.grade = None
s2.save()
查:
s2.grade.name
s2.grade.num
表關聯對象的訪問:
Student的模型類中我們有定義department的屬性,所以當我們去訪問的時候,可以直接通過student.department的形式去找到某個學生的所屬學院是哪個.
那么如果我們也希望在在訪問某個學院的實現對象的學生的時候改怎么訪問呢???
如果模型I有一個ForeignKey,那么該ForeignKey 所指的模型II實例可以通過一個管理器回前面有ForeignKey的模型I的所有實例。默認情況下,這個管理器的名字為foo_set,其中foo 是源模型的小寫名稱。
例子:g3.students_set <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x7f097b7a0b70>
g3.students_set.create(name='王五') 反向增加.
g3.students_set.add(s) #直接加入一個s對象
create,add,立刻馬上操作數據庫,add可以加多個
可以在定義時設置related_name 參數來覆蓋foo_set 的名稱.
添加了related_name的參數后,重新打開一個IDLE,
訪問時就能直接用設置的參數作為屬性了.
處理關聯對象的一些方法:
add(obj1, obj2, ...) 添加的已經存在數據庫的數據
添加一指定的模型對象到關聯的對象集中。
1.d1.student的管理器有add的方法.
2.例子中的s2能添加成功是因為設置了student表中department字段允許為空了.
create(\kwargs) 添加不存在的數據 ,將數據直接存入數據庫
創建一個新的對象,將它保存並放在關聯的對象集返回新創建的對象。
remove(obj1, obj2, ...)
從關聯的對象集中刪除指定的模型對象。
刪除的是關系表中的數據
因為我們有修改student表中的department_id字段允許為空,所以當刪除的時候這個字段值為NULL.刪除字段必須設置null為True
clear() 從關聯的對象集中刪除所有的對象
remove,clear是立刻馬上執行.
g3.student_set.set([s,s2])
set方法先調用clear,然后添加
注意對於所有類型的關聯字段,add()、create()、remove()和clear()都會馬上更新數據庫。換句話說,在關聯的任何一端,都不需要再調用save()方法。
多表查詢----跨關聯關系的查詢:
Django 提供一種強大而又直觀的方式來“處理”查詢中的關聯關系,它在后台自動幫你處理JOIN。 若要跨越關聯關系,只需使用關聯的模型字段的名稱,並使用雙下划線分隔,直至你想要的字段:
例子:Students.objectt.filter(grade__name='django框架') #此sql語句用內連接完成查詢.
查詢學院名字為‘計算機學院’的學生的信息
Student.objects.filter(department__d_name='計算機學院')
它還可以反向工作。若要引用一個“反向”的關系,只需要使用該模型的小寫的名稱。
查詢學生名字中包含 '小' 的學生的學院信息
Department.objects.filter(students_namecontains='小')
查詢學號為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')
ManyToMany
add,set,remove都是我們沒有指定中間表時候使用.
只要是反向,就用模型的小寫加--set.
ManyToManyField相當於一個管理器:
例子:c1.students.all()
通過ManyToManyField字段的介入,就可以不需要中間表進行查詢.
OneToOne反向查詢中不需要set,直接通過模型的小寫調用一個對象,不是管理器.
例子:s1.studentdetail.college
查詢性別為1的學生選擇的課程
res = Course.objects.filter(students__sex=1)
查詢選擇python課程的學生:
Students.objects.filter(course--name--counatins='python')
查詢選擇了英語33期的學生
res = Students.objects.filter(course--name--contains='english',grade--num--contains='33')
查詢報名學費小於3000的學生
Students.objects.filter(enroll--pay--lt=3000)
查詢報名了python的學生所在的年級
Grade.objects.filter(student--course--name--contains='python')
在執行makemigrations的時候,django自動在數據庫中創建一個django-migrations表,記錄執行的遷移文件名,如果手動刪除了遷移文件,再執行makemigrations時,生成的相同的遷移文件名不會執行.所以還要手動在django-migrations表中手動刪除同名記錄,才能執行migrate.但是數據庫沒有相應的回調,執行時會報錯.
遷移回滾
python manage.py migrate teacher 0001 #最后是以前版本的遷移文件名
Students.objects.only('name') ,返回的是一個對象列表,可以索引取其他屬性,提高效率.only查詢id和name,再查詢其他屬性時又執行查詢數據庫.
Students.objects.values('name') ,返回的是一個QuerySet,只能索引取到name字典對象,不可以索引取其他屬性
左連接查詢的一個例子: