ORM
基礎操作
鏈接
mysql
數據庫在
setting.py
中修改數據庫配置文件,本教程咱們以MySQL
爲例'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'orm', # 要連接的數據庫,連接前需要創建好 'USER': 'docker', # 連接數據庫的用戶名 'PASSWORD': 'docker', # 連接數據庫的密碼 'HOST': '127.0.0.1', # 連接主機,默認本級 'PORT': 3306 # 端口 默認3306 }
因爲django默認你導入的驅動是MySQLdb,可是MySQLdb 對於py3有很大問題,所以我們需要的驅動是PyMySQL 所以,我們只需要找到項目名文件下的init,在裏面寫入:
import pymysql pymysql.install_as_MySQLdb()
最後通過兩條數據庫遷移命令即可在指定的數據庫中創建表 :
python manage.py makemigrations python manage.py migrate
小技巧:如果想打印orm轉換過程中的sql,需要在settings中進行如下配置
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
數據表
利用
Django
的orm
創建數據表,不能創建數據庫,用因爲Django
是基於數據表的,不是基於數據庫的。
創建數據表
我們一般在對應模塊下的
model.py
中創建數據表
簡單實例:
class Book(models.Model):
'''
創建Book數據表
'''
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
press = models.CharField(max_length=64)
price = models.DecimalField(max_digits=8, decimal_places=2)
anther = models.CharField(max_length=11)
然後執行數據庫遷移即可。
添加數據
方式一:
res = models.Book.objects.create(
name ="GO寶典",
press ="南京出版社",
price =1220.3,
anther ="Jack"
)
方式二:
res = Book(
name ="LINUX寶典",
press ="河南出版社",
price =10.3,
anther ="Mosson",
text ="String",
email ="[email protected]"
)
res.save()
查詢
基礎查詢
- all(): 查詢所有結果
- filter(**kwargs): 它包含了與所給篩選條件相匹配的對象
- get(**kwargs): 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,如果符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
- exclude(**kwargs): 它包含了與所給篩選條件不匹配的對象
- order_by(*field): 對查詢結果排序
- reverse(): 對查詢結果反向排序
- count(): 返回數據庫中匹配查詢(QuerySet)的對象數量。
- first(): 返回第一條記錄
- last(): 返回最後一條記錄
- exists(): 如果QuerySet包含數據,就返回True,否則返回False
- values 返回一個ValueQuerySet——一個特殊的QuerySet,運行後得到的並不是一系列model的實例化對象,而是一個可迭代的字典序列(在QuertSet中存放字典序列)
Book.objects.all().values("title")
- values_list() 它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列(在QuertSet中存放元組序列)
Book.objects.all().values_list("title")
- distinct 從返回結果中剔除重複紀錄(配合values和values_list使用)
Book.objects.all().distinct()
基於雙下劃線的模糊查詢
Book.objects.filter(price__gt=10, price__lt=20)
- 雙下劃線的查詢列表
__gt : 大於
__lt : 小於
__startswith : 以xxx開頭
__in : 在xxx之中
__contains : 包含(區分大小寫)
__icontains : 包含(不區分大小寫)
__range : 範圍
刪除
- 刪除所有(無返回值)
model_obj.delete()
- 條件刪除(返回刪除的ID)
Book.objects.all().values("title").delete()
修改
- 條件修改
models.Book.objects.filter(price__gt=1000).update(name="PHP")
多表操作
創建數據
publish_v1 = Publish.objects.get(nid=1)
publish_v2 = Publish.objects.get(nid=2)
publish_v3 = Publish.objects.get(nid=3)
res = Book.objects.create(
title = "MacBook Pro",
publishDate = "2018-09-18",
price = 12.34
)
res.publish.add(publish_v1, publish_v2, publish_v3)
刪除數據
res = Book.objects.get(nid=11).delete()
查詢
- 一對多(正向查詢):
# 查詢主鍵爲1的書籍的出版社所在的城市
book_obj=Book.objects.filter(pk=1).first()
# book_obj.publish 是主鍵爲1的書籍對象關聯的出版社對象
print(book_obj.publish.city)
- 一對多(反向查詢):
res = Publish.objects.get(name="北京出版社").book_set.get(nid=12)
- 一對一(正向查詢):
res = Author.objects.filter(name="Alvin").first().antherDetail.telephone
- 一對一(反向查詢):
res = AuthorDetail.objects.filter(telephone=16621068505)
for obj in res:
print(obj.author.name)
- 多對多(正向查詢):
res = Book.objects.filter(title="PHP").first().anther.all()
for obj in res:
print(obj.name)
- 多對多(反向查詢):
res = Author.objects.filter(name="Alvin").first().book_set.all()
for i in res:
print(i.title)
基於雙下劃線的跨表查詢
- 一對多(正向查詢)
res = Book.objects.filter(publish__name="北京出版社").all()
- 一對多(反向查詢)
res = Publish.objects.filter(name="北京出版社").values_list("book__title")
- 多對多(正向查詢):
res = Book.objects.filter(title="PHP").values_list("anther__name")
- 多對多(反向查詢):
res = Author.objects.filter(name="Alvin").values_list("book__title")
- 一對一(正向查詢):
res = Author.objects.filter(name="Alvin").values_list("antherDetail__addr")
- 一對一(反向查詢):
res = AuthorDetail.objects.filter(author__age=23).values_list("author__name")
注:反向查詢時,如果定義了related_name ,則用related_name替換表名
聚合查詢與分組查詢
聚合(aggregate)
res = Book.objects.filter(title="PHP").aggregate(Avg("price"))
分組(annotate)
res = Book.objects.values("price").annotate(c=Count("*"))
附:
from django.db import models
# Create your models here.
class Book(models.Model):
'''
Book數據表
'''
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
# 與出版社表建立一對多的關係
publish = models.ManyToManyField(to="Publish",)
# 與Auther建立多對多的關係
anther = models.ManyToManyField(to="Author",)
class Author(models.Model):
'''
Auther表
'''
nid = models.AutoField(primary_key=True)
name = models.CharField( max_length=32)
age = models.IntegerField()
# 與作者詳情表建立一對一的關係
antherDetail = 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()