django框架是將數據庫信息進行了封裝,採起了html
類——>數據表java
對象——>記錄python
屬性——>字段git
經過這種一一對應方式完成了orm的基本映射
官方文檔:https://docs.djangoproject.com/en/2.2/
1、表單
models中每個繼承於models.Model的類就是一張數據表
如:class AddressInfo就是一張關於地址的數據表
官方文檔:https://docs.djangoproject.com/en/2.2/topics/db/models/
2、字段
文檔地址:https://docs.djangoproject.com/en/2.2/ref/models/fields/
(1)字段設計
1.自增加字段(default=int)程序員
# 自增加字段 Auto = models.AutoField() # 默認爲整型 BigAuto = models.BigAutoField() # 比Auto大
2.二進制的數據sql
# 二進制字段 Binary = models.BinaryField() # 二進制字段
3.boolean類型shell
# Boolean類型 Boolean = models.BooleanField() # 不爲空 NullBoolean = models.NullBooleanField() # 爲空
4.整型數據庫
# 整型 PositiveSmallInteger = models.PositiveSmallIntegerField() # 能存取五個字節的大小 SmallInteger = models.SmallIntegerField() # 能存取六個字節的大小 能夠是正整數也能夠是負整數 PositiveInteger = models.PositiveIntegerField() # 10個字節大小的正整數 Integer = models.IntegerField() # 11個字節大小的正整數 BigInteger = models.BigIntegerField() # 20個字節大小的整形
5.字符型express
# 字符串類型 Char = models.CharField() # varchar Text = models.TextField() # longtext
6.時間類型django
# 時間日期類型 Date = models.DateField() # 年月日 DateTime = models.DateTimeField() # 年月日時分秒 Duration = models.DurationField() # 一段時間 int 底層用Python timedelta實現
7.浮點型
# 浮點型 Float = models.FloatField() # 浮點型 Decimal = models.DecimalField() # 須要指定整數多少位 小數多少位
8.其餘字段
# 其餘字段 Email = models.EmailField() # 郵箱 Image = models.ImageField() # 圖片 File = models.FileField() # 文件 FilePath = models.FilePathField() # 文件路徑 URL = models.URLField() # 網址 UUID = models.UUIDField() # 通用惟一識別碼 GenericIpAddress = models.GenericIPAddressField() # ip地址 ipv4的地址 或者是ipv6的地址
(2)字段參數設計
1.通用參數
# db_column="" 指定在數據庫中的參數 # primary_key=True 設置主鍵 True # verbose_name="" 設置別名 # unique=True 設置字段是否惟一 # null=True, blank=True, db_index=True null是表中的字段是否爲空 blank是表單提交的數據要和null保持一致 不然就會出現錯誤 同時給字段創建索引 # help_text="" 創建幫助文檔 # editable=False 使用戶不能夠修改
# max_length = 20 指定最大長度
2.個別參數具備的字段
# date類型: unique_for_date=True 設置日期必須惟一 還有月和年 # date類型: auto_now_add=True 增長記錄時的時間 插入數據的時間 # date類型: auto_now=True 更新當前記錄的時間 更新數據的時間 # Decimal類型: max_digits=4 總共多少位, decimal_places=2 小數的位數
3.關係型字段
# related_name='' 外鍵查詢的信息 # on_delete: 當外鍵不在的時候進行什麼操做 做爲關係型字段的必須參數(默認順序是外鍵表to和on_delete) # on_delete的六種模式 """ models.CASCADE: 刪除級聯 A表記錄被刪除B表記錄也會被刪除 默認 要設定null=True blank=True models.PROTECT: 刪除時 會報PROTECT ERROR異常 models.SET: 傳一個SET值或者回調函數值 models.SET_NULL: 刪除置空 父表記錄被刪除子表記錄設置成NULL 同時須要指定null=True blank=True models.SET_DEFAULT: 當父表字段被刪除的時候咱們給子表字段設置一個默認值 用default參數指定值 models.DO_NOTHING: 當父表被刪除子表什麼也不作 """
(3)關聯關係
關聯關係分爲三種:一對一,一對多,多對多
1.基類
class Teacher(models.Model): # 教師類 objects = models.Manager() class Meta: verbose_name = "講師信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname
2.一對一
其中的to和on_delete是必須參數,且要設計null和blank都要爲空
class TeacherAssistant(models.Model): # 助教類 objects = models.Manager() # 外鍵關聯 # 一對一 助教和教師 teacher = models.OneToOneField(to=Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="講師")
2.一對多
其中的to和on_delete是必須參數,且要設計null和blank都爲空
class Course(models.Model): objects = models.Manager() # 外鍵關聯 # 一對多 一個講師對應多個課程 # 其中to和on_delete是必須參數 teacher = models.ForeignKey(to=Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='課程講師')
3.多對多
其中的to是必須參數
class Student(models.Model): # 學生類 objects = models.Manager() # 外鍵關聯 # 多對多 學生和課程 course = models.ManyToManyField(to=Course, verbose_name='課程信息')
(4)自關聯
利用自關聯的特性構建一個相似於省市縣的方法
關聯的時候可使用‘self’或者是模型名
class AddressInfo(models.Model): address = models.CharField(max_length=200, null=True, blank=True, verbose_name='地址') pid = models.ForeignKey('self', models.CASCADE, null=True, blank=True, verbose_name='自關聯') # pid = models.ForeignKey('AddressInfo', null=True, blank=True, verbose_name='自關聯') def __str__(self): return self.address
3、元數據
文檔地址:https://docs.djangoproject.com/en/2.2/ref/models/options/
設置數據庫的表名等信息,對數據進行一個操做等
一些meta中的實例,官網有更多的字段介紹和更加詳細的字段信息
class AddressInfo(models.Model): class Meta: ordering = ['pid'] # 指定按照什麼 字段進行排序:-pid 是降序 沒有-表示升序 添加字段的順序表示排序的前後結果 verbose_name = '省市縣' # 設置成一個直觀的名字在admin中 verbose_name_plural = verbose_name # 設置成複數 abstract = True # 不生成數據表 做爲其餘類的基類 permissions = [('定義好的權限', '給權限的說明'), ] # 二元的列表或者是元組 managed = False # 是否按照Django既定的模型類管理 好比是否建立數據表 unique_together = [] # 聯合惟一鍵, 可使用一元列表:只使用一組字段做爲約束條件 二元列表:[[], []] db_table = 'address' # 修改數據庫的表名 app_label = 'app_name' # 定義模型類屬於哪個應用, 在app沒有添加到setting的配置環境中 db_tablespace = 'db_tablespace_name' # 定義數據庫表空間的名字
4、Django的數據表
(1)models生成流程
1.數據表的代碼
class Teacher(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='暱稱', ) introduction = models.TextField(default="這位同窗很懶,什麼也沒有留下來", verbose_name="簡介", ) fans = models.PositiveIntegerField(default=0, verbose_name="粉絲數") create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) objects = models.Manager() class Meta: verbose_name = "講師信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class Course(models.Model): title = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="課程名") course_type = models.CharField(choices=((0, '其餘'), (1, "實戰課"), (2, "免費課程")), max_length=1, default=0, verbose_name="課程類型") price = models.PositiveSmallIntegerField(verbose_name="價格") volume = models.BigIntegerField(verbose_name="銷量") online = models.DateField(verbose_name="上線時間") create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) # 系統本身添加 update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) # 系統本身添加 objects = models.Manager() # 外鍵關聯 # 一對多 一個講師對應多個課程 teacher = models.ForeignKey(to=Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='課程講師') class Meta: verbose_name = "課程信息表" verbose_name_plural = verbose_name def __str__(self): # _get_FIELD_display能夠展現Filed的類型 return f"{self._get_FIELD_display(self.course_type)}-{self.title}" class Student(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='暱稱', ) age = models.PositiveSmallIntegerField(verbose_name="年齡") gender = models.CharField(choices=((1, "男"), (2, "女"), (0, "保密")), max_length=1, default=0, verbose_name="性別") study_time = models.PositiveIntegerField(default=0, verbose_name="學習時長(h)") create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) objects = models.Manager() # 外鍵關聯 # 多對多 學生和課程 course = models.ManyToManyField(to=Course, verbose_name='課程信息') class Meta: verbose_name = "學生信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class TeacherAssistant(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='暱稱', ) hobby = models.CharField(max_length=30, null=True, blank=True, verbose_name='愛好', ) create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) objects = models.Manager() # 外鍵關聯 # 一對一 teacher = models.OneToOneField(to=Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="講師") class Meta: verbose_name = "講師助手信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname
2.在對應的應用的migration中生成對應的migrations文件
經過使用指令:【python manage.py makemigrations】完成數據的遷移,在對應的APP下面的migrations裏面生成遷移數據日誌
3.在django_migrations下面的生成記錄
經過指令:【python manage.py migrate】完成數據的建表信息,將migrations裏面的數據日誌轉成數據庫語言存入數據庫中
4.在數據庫中生成的數據表
5.刪除數據表
所以再刪除的時候按照上面的四步就能夠刪除一個models類
(2)導入數據
1.Django-shell
使用【python manage.py shell】進入到命令行,導入對應的類建立對象完成數據的保存,【from [appname].models import [模板類]】
2.腳本
按照sys、os——>配置環境文件——>導入Django——>導入數據表.嚴格按照這個順序導入數據信息,不然就會報錯
其中settings前面的是項目的名字
參考blog:https://blog.csdn.net/qq_40999403/article/details/80694545
# -*- coding:utf-8 -*- # __author__ == pzq # @email: 1427655779@qq.co import os import sys import random from datetime import date # 將django項目根目錄加入環境變量 parent_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(parent_path) # 引入django配置文件 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "film.settings") # 啓動django import django django.setup() from index.models import Student, Course, TeacherAssistant, Teacher def import_data(): # 使用Django ORM導入數據 # 講師數據 create() Teacher.objects.create(nickname='Jack', introduction="Python工程師", fans=random.randint(500, 1000)) Teacher.objects.create(nickname="Jerry", introduction="Java工程師", fans=random.randint(200, 800)) Teacher.objects.create(nickname="Peter", introduction="PHP工程師", fans=random.randint(400, 700)) Teacher.objects.create(nickname="Kate", introduction="C++工程師", fans=random.randint(100, 400)) # 課程數據 bulk_create() 批量導入數據 # 外鍵的鏈接經過對象 Course.objects.bulk_create([Course(title=f"python入門課程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(1000, 10000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Jack")) for i in range(1, 4)]) Course.objects.bulk_create([Course(title=f"Java入門課程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(2000, 9000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Jerry")) for i in range(1, 5)]) Course.objects.bulk_create([Course(title=f"PHP進階課程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(1000, 4000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Peter")) for i in range(1, 3)]) Course.objects.bulk_create([Course(title=f"C++高階課程{i}", course_type=random.choice((0, 1, 2)), price=random.randint(100, 1000), volume=random.randint(1000, 2000), online=date(random.randint(2010, 2019), random.randint(1, 12), random.randint(1, 28)), teacher=Teacher.objects.get(nickname="Kate")) for i in range(1, 4)]) # 學生數據 # update_or_create() 先經過nickname如今數據庫中找尋這個數據 若是存在就update若是不存在就create # 把主鍵或者惟一鍵放在外面 把其餘參數放在裏面 Student.objects.update_or_create(nickname="A同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) Student.objects.update_or_create(nickname="B同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) Student.objects.update_or_create(nickname="C同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) Student.objects.update_or_create(nickname="D同窗", defaults={"age": random.randint(18, 28), "gender": random.choice((0, 1, 2)), "study_time": random.randint(1000, 2000)}) # 接下來添加外鍵字段 # 正向添加 pk能夠代替主鍵查找 子表關聯到父表 # 銷量大於等於1000的課程 Student.objects.get(nickname="A同窗").course.add(*Course.objects.filter(volume__gte=1000)) # 銷量大於5000的課程 Student.objects.get(nickname="B同窗").course.add(*Course.objects.filter(volume__gt=5000)) # 反向添加 經過課程關聯到學生 # 學習時間大於等於500小時的同窗 Course.objects.get(title="python入門課程1").student_set.add(*Student.objects.filter(study_time__gte=1500)) # 學習時間小於等於500小時的同窗 Course.objects.get(title="python入門課程2").student_set.add(*Student.objects.filter(study_time__lte=1500)) # 助教數據 get_or_create() 先經過nickname的關鍵字或者是主鍵進行查找 若是有就獲取沒有就建立 TeacherAssistant.objects.update_or_create(nickname="助教1", defaults={"hobby": "慕課網學習", "teacher": Teacher.objects.get(nickname="Jack")}) TeacherAssistant.objects.update_or_create(nickname="助教2", defaults={"hobby": "中國Mooc學習", "teacher": Teacher.objects.get(nickname="Jerry")}) TeacherAssistant.objects.update_or_create(nickname="助教3", defaults={"hobby": "程序員客棧", "teacher": Teacher.objects.get(nickname="Peter")}) TeacherAssistant.objects.update_or_create(nickname="助教4", defaults={"hobby": "牛客網", "teacher": Teacher.objects.get(nickname="Kate")}) return True if __name__ == '__main__': try: if import_data(): print("數據導入成功!") except Exception as AddError: print(AddError)
3.fixtures Django serialization ——> model 保存到數據庫
使用指令【python manage.py dumpdata > film.json】輸出數據庫文件
使用指令【python manage.py loaddata film.json】輸入數據到數據庫
4.經過數據庫層面來實現
導入SQL文件等
(3)導出數據
1.mange.py dumpdata > [文件名]
2.使用pycharm或者是Navicat等數據工具來導出
3.使用數據庫層面:MySQL dumpdata來實現
5、models API
queryset文檔:https://docs.djangoproject.com/en/2.2/ref/models/querysets/
(1)查詢介紹
def start(request): """ int類型的操做函數: gte:大於等於 exact:等於 gt:大於 in:在某某以內 isnull:是否爲空 lt:小於 lte:小於等於 range:在什麼範圍內 字符型更多:其中i是忽略大小寫敏感 """ # 1.查詢 檢索 過濾 # 返回的是對象 teacher = Teacher.objects.filter(fans__gte=500) # 是個query集 給字段匹配數據的時候必定要用雙下劃線 # 其中pk是主鍵 在這裏就是nickname的關鍵字 t1 = Teacher.objects.get(pk="Jack") # get只能返回一條結果 全部採起主鍵或者是惟一鍵 t2 = Teacher.objects.all() # 查詢全部數據 返回全部數據的對象集 # # 2.字段匹配大小寫敏感 t3 = Teacher.objects.filter(pk__icontains="A") # 有不少能夠去查看一下官網 # # 3.結果切片 排序 鏈式查詢 # 切片 t3_1 = Teacher.objects.all().order_by('-fans')[1:] # 排序 t4 = Teacher.objects.all().order_by('-fans') # -表明降序 按照老師的粉絲數進行排序 t4_1 = Teacher.objects.all().order_by('fans') # 默認升序 # # 鏈式查詢 t5 = Teacher.objects.filter(fans__gte=500).order_by('fans') # 先獲取一個字段的屬性 在對獲取的數據集在採起升序排序 t6 = Teacher.objects.filter(fans__gte=500).order_by('-fans') # 先獲取一個字段的屬性 在對獲取的數據集在採起降序排序 # 4.查詢原生sql語句 經過query進行查詢 print(f"我是查詢語句{str(t6.query)}") return render(request, 'learn_set.html')
(2)返回新的queryset的API
def start(request): """ 查詢介紹 返回新的 Query API """ # 1.all() filter() order_by():排序 exclude():除了xx元素之外 reverse():反向排序 distinct():去重 # 能夠用pk代替關鍵字 exclude除去含有關鍵字的信息 st_0 = Student.objects.all().exclude(pk="A同窗") # print(f"我是exclude:{st_0}") # 使用reverse的時候能夠在Meta中用ordering指定排序的字段 多個ordering的時候取第一個 默認按照關鍵字的順序輸出 st_0_1 = Student.objects.reverse() # print(f"我是reverse:{st_0_1}") # 2.extra():給字段取別名 defer():排除一些字段 only():選擇一些字段 # extra(): extra(select={"[要取的別名]": "[原來字段名]"}) st_1 = Student.objects.all().extra(select={"name": "nickname"}) # for i in st_1: # print(f"我是extra:{i.name}") st_2 = Student.objects.all().only('nickname', 'age') # print(f"我是only_query:{str(st_2.query)}") # 3.values():字典 values_list():元組 獲取字典或者是元組形式的queryset # values() 輸出的是dict類型的 st_3_0 = TeacherAssistant.objects.values('nickname', 'hobby') # print(f"我是values:{st_3_0}") # values_list() 輸出的是元組類型的數據 st_3_1 = TeacherAssistant.objects.values_list('nickname', flat=True) # flat:將單個字段的數據直接放到列表裏面 只限於獲取單個數據的信息 # print(f"我是values_list:{st_3_1}") # 4.根據時間和日期獲取查詢集 dates:年月日 datetimes年月日時分秒查詢字段多一點有時分秒 使用什麼查詢方式取決於定義字段的類型 # datetimes('[查詢時間的字段]', 'month', order='DESC') st_4 = Course.objects.dates('online', 'year', order='DESC') # ASC 升序排列(默認) DESC降序排列 # print(f"我是dates:{st_4}") # 5.集合的運算 union():並集 intersection():交集 difference():差集 s_1 = Student.objects.filter(study_time__gte=1600) # 大於等於1500 s_2 = Student.objects.filter(study_time__lte=1500) # 小於等於1600 # print(f"我是union:{s_1.union(s_2)}") # 只支持取並集 # print(f"我是intersection:{s_1.intersection(s_2)}") # 數據庫不支持 # print(f"我是difference:{s_1.difference(s_2)}") # 數據庫不支持 # 6.優化查詢api select_related() 一對一 多對一的優化查詢 prefetch_related() 一對多 多對多的優化查詢 # select_related() # 經過課程獲取講師信息 查詢相關信息經過外接字段進行鏈接 c_1 = Course.objects.all().select_related('teacher') for c in c_1: print(f"課程信息:{c.title}--{c.teacher.nickname}--{c.teacher.fans}") # prefetch_related() 多對多 s_1 = Student.objects.filter(age__lte=30).prefetch_related('course') for s in s_1: for i in s.course.all(): # 獲取到的是managerelmanage的對象 print(f"{s.nickname}--{i.title}") # 輸出課程的信息 # 反向查詢:根據父表查詢子表 # 經過在數據段的對應關係 [字表的表名]_set能夠替換爲related_name的值 t_1 = Teacher.objects.get(nickname='Jack').teach.all() print(f"我是反向查詢{t_1}") # 7.annotate() 使用聚合計數、求和、平均數、raw()、執行原生的SQL # 求和 sum_1 = Course.objects.values('[處理表單]').annotate(vol=Sum('[處理字段]')) sum_1 = Course.objects.values('teacher').annotate(vol=Sum('volume')) print(f"我是求和:{sum_1}") # 平均值 ave_1 = Student.objects.values('course').annotate(time=Avg('study_time')) print(f"我是求平均值:{ave_1}") # row能夠寫原生數據語句 裏面執行原生的SQL語句 # 參考文檔 # https://docs.djangoproject.com/en/2.2/topics/db/sql/
(3)不返回新的query的API
def start(request): """ 不返回查詢集的API """ # 參考文檔:https://docs.djangoproject.com/en/2.2/ref/models/querysets/#raw # 1.獲取對象 get() get_or_create() first() last() latest() earliest() in_bulk() # get() 獲取對象 # get_or_create() 有數據就經過get獲取沒有就建立數據 # first() # 第一條記錄 # print(f"我是first:{Course.objects.first()}") # last() # 最後一條記錄 # print(f"我是last:{Course.objects.last()}") # latest() # 最近的記錄 須要在模型類裏面設置 get_latest_by = [建立的字段] 表明根據建立的字段進行排序 # 也能夠在排序的時候本身指定 更加方便咱們本身的操做 # print(f"我是latest{Course.objects.latest('online')}") # earliest() # 最先的記錄 # print(f"我是earliest{Course.objects.earliest('update_date')}") # in_bulk() 批量返回對象 根據主鍵的值傳遞一個列表 列表中傳遞主鍵的值 # print(Course.objects.in_bulk(['Java入門課程1', 'Java入門課程2', 'python入門課程2'])) # 2.建立對象 create():建立對象 bulk_create():批量建立對象 create_or_update():若是沒有就建立有就更新 # bulk_create:給函數建立一個列表 # 3.更新對象 update():更新 update_or_create():更新或建立 # update() # print(f"我是更新前的價格:{Course.objects.get(title='C++高階課程1').price}") # Course.objects.filter(title="C++高階課程1").update(price=568) # print(f"我是更新後的價格:{Course.objects.get(title='C++高階課程1').price}") # 4.刪除對象 delete():使用filter過濾 # print(Course.objects.filter(title="test_1").delete()) # 5.其餘操做 exist():是否存在 count():統計個數 aggregate():聚合 # exist() # print(Course.objects.filter(title="test_1").exists()) # print(Course.objects.filter(title="PHP進階課程2").exists()) # count()記錄數據表中的數據個數 # print(Course.objects.count()) # annotate():和value配合使用 對分組結果進行排序 aggregate():對數據庫中的數據結果進行處理 # print(Course.objects.aggregate(Max('price'), Min('price'), Avg('price'), Sum('volume'))) return render(request, 'learn_set.html')
(4)自定義聚類查詢
1.自定義查詢方法
在individual.py中加入如下代碼
from django.db import models class Concat(models.Aggregate): """ORM用來分組顯示其餘字段 至關於group_concat""" function = 'GROUP_CONCAT' template = '%(function)s(%(distinct)s%(expressions)s)' def __init__(self, expression, distinct=False, **extra): super(Concat, self).__init__( expression, distinct='DISTINCT ' if distinct else '', output_field=models.CharField(), **extra)
2.引用
在views.py中的引用
from .individual import Concat def start(request): """ 自定義聚合查詢 """ # 這個title對應查詢結果中的key Concat裏面的纔是咱們須要查詢的字段 course = Course.objects.values('teacher').annotate(title=Concat('title')) for c in course: print(c) return render(request, 'learn_set.html')
(5)F對象查詢
官方文檔:https://docs.djangoproject.com/en/2.2/ref/models/expressions/#django.db.models.F
def start(request): """ F查詢 """ # 操做字段數據或者是將一個字段與另外一個字段進行比較 # # 將全部的價格減11 # Course.objects.update(price=F('price') - 11) # # 獲取銷量大於價格10倍的字段 # course = Course.objects.filter(volume__gte=F('price') * 10) # for c in course: # print(f"{c.title}--{c.price}--{c.volume}") return render(request, 'learn_set.html')
(6)Q對象查詢
官方文檔:https://docs.djangoproject.com/en/2.2/ref/models/querysets/#q-objects
def start(request): """ Q對象結合 &:and |:or :not 實現複雜的查詢 """ # 查詢全部Java課程 而且銷量大於等於5000 print(Course.objects.filter(Q(title__icontains='java') & Q(volume__gte=5000))) # 查詢全部Python語言或者是銷量小於2000的課程 print(Course.objects.filter(Q(title__icontains='python') | Q(volume__lte=2000))) return render(request, 'learn_set.html')
(7)模型類實例:
class Teacher(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='暱稱', ) introduction = models.TextField(default="這位同窗很懶,什麼也沒有留下來", verbose_name="簡介", ) fans = models.PositiveIntegerField(default=0, verbose_name="粉絲數") create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) # 每個非抽象model類必須Manager添加一個實例 objects = models.Manager() class Meta: verbose_name = "講師信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class Course(models.Model): title = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="課程名") course_type = models.CharField(choices=((0, '其餘'), (1, "實戰課"), (2, "免費課程")), max_length=1, default=0, verbose_name="課程類型") price = models.PositiveSmallIntegerField(verbose_name="價格") volume = models.BigIntegerField(verbose_name="銷量") online = models.DateField(verbose_name="上線時間") create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) # 系統本身添加 update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) # 系統本身添加 objects = models.Manager() # 外鍵關聯 # 多對一 多個課程對應一個講師 teacher = models.ForeignKey(to=Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='課程講師', related_name='teach') class Meta: verbose_name = "課程信息表" verbose_name_plural = verbose_name # 根據建立的字段進行排序 方便latest和earliest進行排序 也能夠在排序時指定 # get_latest_by = 'online' def __str__(self): # get_[要展現的字段]_display()就能夠輸出了 如2--python入門課程1>, return f"{self.get_course_type_display()}--{self.title}" class Student(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='暱稱', ) age = models.PositiveSmallIntegerField(verbose_name="年齡") gender = models.CharField(choices=((1, "男"), (2, "女"), (0, "保密")), max_length=1, default=0, verbose_name="性別") study_time = models.PositiveIntegerField(default=0, verbose_name="學習時長(h)") create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) objects = models.Manager() # 外鍵關聯 # 多對多 學生和課程 course = models.ManyToManyField(to=Course, verbose_name='課程信息') class Meta: # 指定多個時 按第一個進行排序 # 不指定根據關鍵字的順序進行排序 如在數據表中添加的數據順序 ordering = ['study_time'] verbose_name = "學生信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname class TeacherAssistant(models.Model): nickname = models.CharField(max_length=30, primary_key=True, db_index=True, verbose_name='暱稱', ) hobby = models.CharField(max_length=30, null=True, blank=True, verbose_name='愛好', ) create_date = models.DateField(auto_now_add=True, verbose_name='建立時間', ) update_date = models.DateField(auto_now=True, verbose_name='更新時間', ) objects = models.Manager() # 外鍵關聯 # 一對一 若是on_delete置空就要將null, blank都設置爲空 teacher = models.OneToOneField(to=Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="講師") class Meta: verbose_name = "講師助手信息表" verbose_name_plural = verbose_name def __str__(self): return self.nickname
6、總結
本篇blog簡單的介紹了orm的內容,也是Django後端內容中最爲重要的一個部分,其餘詳情請參考Django的官方文檔
原文出處:https://www.cnblogs.com/future-dream/p/10604600.html