django操作資料庫常用命令
一文讀懂|Django之Model操作資料庫詳解
菲宇 網際網路工作者一、django ORM簡介
O(objects):類和物件。R(Relation):關係,關係資料庫中的表格。M(Mapping):對映。
Django ORM框架的功能:
- 建立模型類和表之間的對應關係,允許我們通過面向物件的方式來操作資料庫。
- 根據設計的模型類生成資料庫中的表格。
- 通過方便的配置就可以進行資料庫的切換。
二、 資料庫的配置
Django可以配置使用sqlite3,mysql,oracle,postgresql等資料庫。Django預設使用的是sqlite3資料庫,settigs.py裡面:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',#預設使用的資料庫引擎是sqlite3,專案自動建立
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),#指定資料庫所在的路徑
}
}
Django專案也可以配置使用mysql資料庫,使用如下配置:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql',#表示使用的是mysql資料庫的引擎 'NAME': 'db1', #資料庫的名字,可以在mysql的提示符下先建立好 'USER':'root', #資料庫使用者名稱 'PASSWORD':'', #資料庫密碼 'HOST':'', #資料庫主機,留空預設為"localhost" 'PORT':'3306', #資料庫使用的埠 } }
配置好資料庫的資訊後還必須安裝資料庫的驅動程式,Django預設匯入的mysql的驅動程式是MySQLdb,然而MySQLdb對於py3支援不全,所以這裡使用PyMySQL。
pip install pymysql
在專案名檔案下的__init__.py檔案中寫入如下配置:
import pymysql
pymysql.install_as_MySQLdb()
三、建立資料庫表結構檔案
1、生成一個簡單的資料庫表:
在未指定primary_key的情況下,Django會預設建立一個id自增欄位作為主鍵。
from django.db import models class Account(models.Model): account_name = models.CharField(max_length=20) account_id = models.IntegerField(primary_key=True) balance = models.DecimalField(max_digits=2, decimal_places=2)
2、執行命令生成到資料庫
python manage.py makemigrations
python manage.py migrate # 生成資料表
四、資料庫欄位
AutoField(Field) - int自增列,必須填入引數 primary_key=True
BigAutoField(AutoField) - bigint自增列,必須填入引數 primary_key=True
SmallIntegerField(IntegerField): - 小整數 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整數 0 ~ 32767
IntegerField(Field) - 整數列(有符號的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整數 0 ~ 2147483647
BigIntegerField(IntegerField): - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field) - 布林值型別
NullBooleanField(Field): - 可以為空的布林值
CharField(Field) - 字元型別
- 必須提供max_length引數, max_length表示字元長度
TextField(Field) - 文字型別
EmailField(CharField): - 字串型別,Django Admin以及ModelForm中提供驗證機制
IPAddressField(Field) - 字串型別,Django Admin以及ModelForm中提供驗證 IPV4 機制
GenericIPAddressField(Field) - 字串型別,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6
- 引數:
protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定為True,則輸入::ffff:192.0.2.1時候,可解析為192.0.2.1,開啟刺功能,需要protocol="both"
URLField(CharField) - 字串型別,Django Admin以及ModelForm中提供驗證 URL
SlugField(CharField) - 字串型別,Django Admin以及ModelForm中提供驗證支援 字母、數字、下劃線、連線符(減號)
CommaSeparatedIntegerField(CharField) - 字串型別,格式必須為逗號分割的數字
UUIDField(Field) - 字串型別,Django Admin以及ModelForm中提供對UUID格式的驗證
FilePathField(Field) - 字串,Django Admin以及ModelForm中提供讀取資料夾下檔案的功能
- 引數:
path, 資料夾路徑
match=None, 正則匹配
recursive=False, 遞迴下面的資料夾
allow_files=True, 允許檔案
allow_folders=False, 允許資料夾
FileField(Field) - 字串,路徑儲存在資料庫,檔案上傳到指定目錄
- 引數:
upload_to = "" 上傳檔案的儲存路徑
storage = None 儲存元件,預設django.core.files.storage.FileSystemStorage
ImageField(FileField) - 字串,路徑儲存在資料庫,檔案上傳到指定目錄
- 引數:
upload_to = "" 上傳檔案的儲存路徑
storage = None 儲存元件,預設django.core.files.storage.FileSystemStorage
width_field=None, 上傳圖片的高度儲存的資料庫欄位名(字串)
height_field=None 上傳圖片的寬度儲存的資料庫欄位名(字串)
DateTimeField(DateField) - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field) - 時間格式 HH:MM[:ss[.uuuuuu]]
DurationField(Field) - 長整數,時間間隔,資料庫中按照bigint儲存,ORM中獲取的值為datetime.timedelta型別
FloatField(Field) - 浮點型
DecimalField(Field) - 10進位制小數
- 引數:
max_digits,小數總長度
decimal_places,小數位長度
BinaryField(Field)- 二進位制型別
五、資料庫欄位引數
null 資料庫中欄位是否可以為空
db_column 資料庫中欄位的列名
default 資料庫中欄位的預設值
primary_key 資料庫中欄位是否為主鍵
db_index 資料庫中欄位是否可以建立索引
unique 資料庫中欄位是否可以建立唯一索引
unique_for_date 資料庫中欄位【日期】部分是否可以建立唯一索引
unique_for_month 資料庫中欄位【月】部分是否可以建立唯一索引
unique_for_year 資料庫中欄位【年】部分是否可以建立唯一索引
verbose_name Admin中顯示的欄位名稱
blank Admin中是否允許使用者輸入為空
editable Admin中是否可以編輯
help_text Admin中該欄位的提示資訊
choices Admin中顯示選擇框的內容,用不變動的資料放在記憶體中從而避免跨表操作
如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
error_messages 自定義錯誤資訊(字典型別),從而定製想要顯示的錯誤資訊;
字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
如:{'null': "不能為空.", 'invalid': '格式錯誤'}
validators 自定義錯誤驗證(列表型別),從而定製想要的驗證規則
from django.core.validators import RegexValidator
from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
如:
test = models.CharField(
max_length=32,
error_messages={
'c1': '優先錯資訊1',
'c2': '優先錯資訊2',
'c3': '優先錯資訊3',
},
validators=[
RegexValidator(regex='root_\d+', message='錯誤了', code='c1'),
RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'),
EmailValidator(message='又錯誤了', code='c3'), ]
)
六、資料庫Meta元資訊
class UserInfo(models.Model):
nid = models.AutoField(primary_key=True)
username = models.CharField(max_length=32)
class Meta:
# 資料庫中生成的表名稱 預設 app名稱 + 下劃線 + 類名
db_table = "table_name"
# 聯合索引
index_together = [
("pub_date", "deadline"),
]
# 聯合唯一索引
unique_together = (("driver", "restaurant"),)
# admin中顯示的表名稱
verbose_name
# verbose_name加s
verbose_name_plural
七、關係欄位
關係欄位用於儲存資料表之間的關係,包括ForeignKey, ManyToManyField等。
1、ForeignKey
ForeignKey(ForeignObject) # ForeignObject(RelatedField)
to, # 要進行關聯的表名
to_field=None, # 要關聯的表中的欄位名稱
on_delete=None, # 當刪除關聯表中的資料時,當前表與其關聯的行的行為
- models.CASCADE,刪除關聯資料,與之關聯也刪除
- models.DO_NOTHING,刪除關聯資料,引發錯誤IntegrityError
- models.PROTECT,刪除關聯資料,引發錯誤ProtectedError
- models.SET_NULL,刪除關聯資料,與之關聯的值設定為null(前提FK欄位需要設定為可空)
- models.SET_DEFAULT,刪除關聯資料,與之關聯的值設定為預設值(前提FK欄位需要設定預設值)
- models.SET,刪除關聯資料,
a. 與之關聯的值設定為指定值,設定:models.SET(值)
b. 與之關聯的值設定為可執行物件的返回值,設定:models.SET(可執行物件)
def func():
return 10
class MyModel(models.Model):
user = models.ForeignKey(
to="User",
to_field="id"
on_delete=models.SET(func),)
related_name=None, # 反向操作時,使用的欄位名,用於代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作時,使用的連線字首,用於替換【表名】 如: models.UserGroup.objects.filter(表名__欄位名=1).values('表名__欄位名')
limit_choices_to=None, # 在Admin或ModelForm中顯示關聯資料時,提供的條件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
db_constraint=True # 是否在資料庫中建立外來鍵約束
parent_link=False # 在Admin中是否顯示關聯資料
2、OneToOneField
OneToOneField(ForeignKey)
to, # 要進行關聯的表名
to_field=None # 要關聯的表中的欄位名稱
on_delete=None, # 當刪除關聯表中的資料時,當前表與其關聯的行的行為
###### 對於一對一 ######
# 1. 一對一其實就是 一對多 + 唯一索引
# 2.當兩個類之間有繼承關係時,預設會建立一個一對一欄位
# 如下會在A表中額外增加一個c_ptr_id列且唯一:
class C(models.Model):
nid = models.AutoField(primary_key=True)
part = models.CharField(max_length=12)
class A(C):
id = models.AutoField(primary_key=True)
code = models.CharField(max_length=1)
3、ManyToManyField
ManyToManyField(RelatedField)
to, # 要進行關聯的表名
related_name=None, # 反向操作時,使用的欄位名,用於代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作時,使用的連線字首,用於替換【表名】 如: models.UserGroup.objects.filter(表名__欄位名=1).values('表名__欄位名')
limit_choices_to=None, # 在Admin或ModelForm中顯示關聯資料時,提供的條件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
symmetrical=None, # 僅用於多對多自關聯時,symmetrical用於指定內部是否建立反向操作的欄位
# 做如下操作時,不同的symmetrical會有不同的可選欄位
models.BB.objects.filter(...)
# 可選欄位有:code, id, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)
# 可選欄位有: bb, code, id, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)
through=None, # 自定義第三張表時,使用欄位用於指定關係表
through_fields=None, # 自定義第三張表時,使用欄位用於指定關係表中那些欄位做多對多關係表
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64)
db_constraint=True, # 是否在資料庫中建立外來鍵約束
db_table=None, # 預設建立第三張表時,資料庫中表的名稱
八、資料庫基本操作
#建立一個書的類,繼承models類
class Book(models.Model):
#用models類建立書的名字,型別為字串,CharField相當於mysql語句中的varchar,欄位最長為32
title = models.CharField(max_length=32)
#建立書的價格,型別為浮點型,小數點前最長4位,小數點後最長2位
price = models.DecimalField(max_digits=6, decimal_places=2)
#建立書的出版社資訊,其與出版社的外來鍵關係為一對多,所以用外來鍵
publish = models.ForeignKey(Publish)
#建立書的出版日期,型別為日期
publication_date = models.DateField()
#建立書的型別資訊,為字串型別,最長為20
classification=models.CharField(max_length=20)
#建立書的作者資訊,書籍與作者的關係為多對多,所以使用many-to-many
authors = models.ManyToManyField("Author")
1、增
1.1一對一資訊的建立
a、使用create方式
方式一: Publish.objects.create("name"="人民出版社",city="北京"}
方式二: Publish.objects.create(**{"name":"文藝出版社","city":"上海"}}
b、使用save方式
方式一:
book1=Book(title="python",price="88",publish_id="1",publication_date="2017-06-18")
方式二:
author1=Author(name="jerry")
1.2一對多的資訊的建立(Foreignkey)
方式一:
#獲取出版社物件
publish_obj=Publish.objects.get(id=4)
#將出版社的物件繫結到書籍的記錄中
Book.objects.create(
title="python",
price=48.00,
publication_date="2017-07-12",
publish=publish_obj,
)
方式二:
#直接把出版社的id號插入到書籍的記錄中
Book.objects.create(
title="python",
price=48.00,
publish_id=2,
publication_date="2017-06-18",
)
1.3多對多資訊的建立(ManyToManyField())
a、為一本書新增多個作者
author1=Author.objects.get(id=1)#獲取id號為1的作者物件
author2=Author.objects.filter(name="tom")#獲取名字為"tom"的作者物件
book1=Book.objects.get(id=2)#獲取id號為2的書籍物件
book1.authors.add(author1,author2)#為書籍物件新增多個作者物件
也可以用這種方式:
book1.authors.add(*[author1,author2])#為書籍物件新增作者物件的列表
book1.authors.remove(*[author1,author2])#刪除指定書籍的所有作者
b、為一個作者新增多本書
author_obj = Author.objects.filter(name="jerry")#獲取名字為"jerry"的作者物件
book_obj=Book.objects.filter(id__gt=3)#獲取id大於3的書籍物件集合
author_obj.book_set.add(*book_obj)#為作者物件新增書籍物件集合
author_obj.book_set.remove(*book_obj)#刪除指定作者物件所有的書籍
使用models.ManyToManyField()會自動建立第三張表
1.4手動建立多對多的作者與書籍資訊表
class Book2Author(models.Models):
author=models.ForeignKey("Author")#為作者指定Author這張表做為外來鍵
book=models.ForeignKey("Book")#為書籍指定Book這張表做為外來鍵
author_obj=models.Author.objects.filter(id=3)[0]#獲取Author表中id為3的作者物件
book_obj=models.Book.objects.filter(id=4)[0]#獲取Book表中id為4的書籍物件
方式一:
obj1=Book2Author.objects.create(author=author_obj,book=book_obj)
obj1.save()
方式二:
obj2=Book2Author(author=author_obj,book=book_obj)
obj2.save()
2、刪
Book.objects.filter(id=1).delete()
3、改
3.1使用save方法將所有屬性重新設定一遍,效率低
author1=Author.objects.get(id=3)#獲取id為3的作者物件
author1.name="jobs"#修改作者物件的名字
author1.save()#把更改寫入資料庫
3.2使用update方法直接設定對就的屬性
Publish.objects.filter(id=2).update(name="北京出版社")
注意:update()是QuerySet物件的一個方法,get返回的是一個model物件,其沒有update方法.
filter返回的是一個QuerySet物件,filter裡可以設定多個過濾條件
4、查
查詢資料使用QuerySet API。 QuerySet是惰性執行的,建立Query Set不會訪問資料庫,只有在訪問具體查詢結果的時候才會訪問資料庫。
4.1查詢方法:
filter(**kwargs) 包含了與所給篩選條件相匹配的物件
all() 查詢所有結果
get(**kwargs) 返回與所給篩選條件相匹配的物件,返回結果有且只有一個,如果符合篩選條件的物件超過一個或者沒有都是報錯
values(*field) 返回一個ValueQuerySet,執行後得到的並不是一系列model的例項化物件,而是一個可迭代的字典序列
exclude(**kwargs) 包含了與所給的篩選條件不匹配的物件
order by(*field) 對查詢結果排序
reverse() 對查詢結果反向排序
distinct() 從返回結果中剔除重複記錄
values_list(*field) 與values()非常相似,返回一個元組序列,values返回一個字典序列
count() 返回資料庫中匹配的記錄的數量
first() 返回資料庫中匹配的物件的第一個物件
last() 返回資料庫中匹配的物件的最後一個物件
exists() 判斷一個物件集合中是否包含指定物件,包含返回True,不包含返回False
exclude() 排除滿足條件的物件
annotate() 使用聚合函式
dates() 根據日期獲取查詢集
datetimes() 根據時間獲取查詢集
none() 建立空的查詢集
union() 並集
intersection() 交集
difference() 差集
select_related() 附帶查詢關聯物件
prefetch_related() 預先查詢
extra() 附加SQL查詢
defer() 不載入指定欄位
only() 只加載指定的欄位
using() 選擇資料庫
select_for_update() 鎖住選擇的物件,直到事務結束。
raw() 接收一個原始的SQL查詢
1.filter():
filter(**kwargs)
返回滿足查詢引數的物件集合。
查詢的引數(**kwargs)應該滿足下文欄位查詢中的格式。多個引數之間是和AND的關係。
Student.objects.filter(age__lt=10)#查詢滿足年齡小於10歲的所有學生物件
2.exclude()
exclude(**kwargs)
返回一個新的QuerySet,它包含不滿足給定的查詢引數的物件
Student.objects.exclude(age__gt=20, name='lin')#排除所有年齡大於20歲且名字為“lin”的學員集
3.annotate():
nnotate(args, *kwargs)
使用提供的聚合表示式查詢物件。
表示式可以是簡單的值、對模型(或任何關聯模型)上的欄位的引用或者聚合表示式(平均值、總和等)。
annotate()的每個引數都是一個annotation,它將新增到返回的QuerySet每個物件中。
關鍵字引數指定的Annotation將使用關鍵字作為Annotation 的別名。 匿名引數的別名將基於聚合函式的名稱和模型的欄位生成。 只有引用單個欄位的聚合表示式才可以使用匿名引數。 其它所有形式都必須用關鍵字引數。
例如,如果正在操作一個Blog列表,你可能想知道每個Blog有多少Entry:
>>> from django.db.models import Count
>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42
4.order_by():
order_by(*fields)
預設情況下,根據模型的Meta類中的ordering屬性對QuerySet中的物件進行排序
Student.objects.filter(school="陽關小學").order_by('-age', 'name')
上面的結果將按照age降序排序,然後再按照name升序排序。"-age"前面的負號表示降序順序。 升序是預設的。 要隨機排序,使用"?",如下所示:
Student.objects.order_by('?')
5. reverse():
reverse()
反向排序QuerySet中返回的元素。 第二次呼叫reverse()將恢復到原有的排序。
如要獲取QuerySet中最後五個元素,可以這樣做:
my_queryset.reverse()[:5]
這與Python直接使用負索引有點不一樣。 Django不支援負索引。
6.distinct():
distinct(*fields)
去除查詢結果中重複的行。
預設情況下,QuerySet不會去除重複的行。當查詢跨越多張表的資料時,QuerySet可能得到重複的結果,這時候可以使用distinct()進行去重。
7. values():
values(fields, *expressions)
返回一個包含資料的字典的queryset,而不是模型例項。
每個字典表示一個物件,鍵對應於模型物件的屬性名稱。如:
# 列表中包含的是Student物件
>>> Student.objects.filter(name__startswith='Lin')
<QuerySet [<Student: Lin Student>]>
# 列表中包含的是資料字典
>>> Student.objects.filter(name__startswith='Lin').values()
<QuerySet [{'id': 1, 'name': 'Linxiao', 'age': 20}]>
另外該方法接收可選的位置引數*fields,它指定values()應該限制哪些欄位。如果指定欄位,每個字典將只包含指定的欄位的鍵/值。如果沒有指定欄位,每個字典將包含資料庫表中所有欄位的鍵和值。如下:
>>> Student.objects.filter(name__startswith='Lin').values()
<QuerySet [{'id': 1, 'name': 'Linxiao', 'age': 20}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Linxiao'}]>
8.values_list():
values_list(*fields, flat=False)
與values()類似,只是在迭代時返回的是元組而不是字典。每個元組包含傳遞給values_list()呼叫的相應欄位或表示式的值,因此第一個專案是第一個欄位等。 像這樣:
>>> Student.objects.values_list('id', 'name')
獲取資料表的全部資料記錄:
Account.objects.all()
返回值可以進行切片,但不支援負索引。或者使用:
Account.objects.get(field_name=val)
示例:
Account.objects.get(account_name='john')
或者使用過濾器查詢多條記錄:
Account.objects.filter(accounnt_name=val)
嚴格等於
Account.objects.filter(account_name__iexact=val)
忽略大小寫
Account.objects.filter(account_name__contains=val)
名稱中包含val
Account.objects.filter(account_name__icontains=val)
忽略大小寫,包含
Account.objects.filter(account_name__regex=val)
正則表示式
Account.objects.filter(account_name__iregex=val)
正則表示式,忽略大小寫
與filter相反exclude用於返回不滿足條件的查詢結果。
Account.objects.exclude(account_name__contains=val)
filter與exclude可以進行鏈式查詢
Account.objects.exclude(account_name__contains='john').exlucde(balance=0)
對於查詢結果可以使用distinct()去重或者使用order_by(field)進行排序。
Account.objects.filter(account_name__regex=val).distinct()
Account.objects.filter(account_name__regex=val).oreder_by('balance')
使用reverse()方法可以反轉結果集中的元素順序,呼叫兩次將會恢復原順序。
從SQL 的角度,QuerySet和SELECT 語句等價,過濾器是像WHERE 和LIMIT 一樣的限制子句。
like:
__exact 精確等於 like 'aaa'
__iexact 精確等於 忽略大小寫 ilike 'aaa'
__contains 包含 like '%aaa%'
__icontains 包含,忽略大小寫 ilike '%aaa%',但是對於sqlite來說,contains的作用效果等同於icontains。
in:
__in
查詢在某一範圍的書
Book.objects.filter(publish__in=[10, 20, 30])
is null / is not null:
__isnull 判空
Book.objects.filter(name__isnull=True) // 查詢使用者名稱為空的書
Publish.objects.filter(name__isnull=False) // 查詢使用者名稱不為空的書
不等於/不包含於:
Book.objects.filter().excute(publishe=10) // 查詢出版社不為10的書
Book.objects.filter().excute(publish__in=[10, 20]) // 查詢出版社不在 [10, 20] 的書
其他常用模糊查詢:
__startswith 以…開頭
__istartswith 以…開頭 忽略大小寫
__endswith 以…結尾
__iendswith 以…結尾,忽略大小寫
__range 在…範圍內
__year 日期欄位的年份
__month 日期欄位的月份
__day 日期欄位的日
4.2雙下劃線(__)查詢
a、雙下劃線(__)之單表條件查詢
例子:
table1.objects.filter(id__lt=10,id__gt=1)#獲取id小於10,且大於1的記錄
table1.objects.filter(id__in=[11,22,33,44])#獲取id在[11,22,33,44]中的記錄
table1.objects.exclude(id__in=[11,22,33,44])#獲取id不在[11,22,33,44]中的記錄
table1.objects.filter(name__contains="content1")#獲取name中包含有"contents"的記錄(區分大小寫)
table1.objects.filter(name__icontains="content1")#獲取name中包含有"content1"的記錄(不區分大小寫)
table1.objects.filter(id__range=[1,4])#獲取id在1到4(不包含4)之間的的記錄
b、雙下劃線(__)之多表條件查詢
正向查詢(條件)之一對一查詢
#查詢書名為"python"的書的id號
res3=Book.objects.filter(title="python").values("id")
print(res3)
正向查詢(條件)之一對多查詢
#查詢書名為"python"的書對應的出版社的地址
res4=Book.objects.filter(title="python").values("publisher__city")
print(res4)
#查詢"aaa"作者所寫的所有的書的名字
res5=Book.objects.filter(author__name="aaa").values("title")
print(res5)
#查詢"aaa"作者所寫的所有的書的名字(與上面的用法沒區別)
res6=Book.objects.filter(author__name="aaa").values("title")
print(res6)
反向查詢之一對多查詢
#查詢出版了書名為"python"這本書的出版社的名字
res7=Publisher.objects.filter(book__title="python").values("name")
print(res7)
#查詢寫了書名為"python"的作者的名字
res8=Publisher.objects.filter(book__title="python").values("book__authors")
print(res8)
反向查詢之多對多查詢
#查詢所寫的書名為"python"的作者的名字
res9=Author.objects.filter(bool__title="python").values("name")
print(res9)
條件查詢即與物件查詢對應,是指filter,values等方法中的通過__來明確查詢條件
4.3F查詢和Q查詢
F查詢專門取物件中某列值的操作,F的作用:用來批量修改資料的
#匯入F
from django.db.models import F
#把table1表中的num列中的每一個值在的基礎上加10
table1.objects.all().update(num=F("num")+10)
Q構建搜尋條件, Q的作用:Q是用來做條件查詢的
#匯入Q
from django.db.models import Q
Q物件可以對關鍵字引數進行封裝,從而更好的應用多個查詢
#查詢table2表中以"aaa"開頭的所有的title列
q1=table2.objects.filter(Q(title__startswith="aaa")).all()
print(q1)
Q物件可以組合使用&,|操作符,當一個操作符是用於兩個Q物件時,會產生一個新的Q物件
#查詢以"aaa"開頭,或者以"bbb"結尾的所有title
Q(title__startswith="aaa") | Q(title__endswith="bbb")
Q物件可以用"~"操作符放在表示式前面表示否定,也可允許否定與不否定形式的組合
#查詢以"aaa"開頭,且不以"bbb"結尾的所有title
Q(title__startswith="aaa") & ~Q(title__endswith="bbb")
Q物件可以與關鍵字引數查詢一起使用,Q物件放在關鍵字查詢引數的前面
查詢條件:
#查詢以"aaa"開頭,以"bbb"結尾的title且書的id號大於4的記錄
Q(title__startswith="aaa") | Q(title__endswith="bbb"),book_id__gt=4
九、例項
1、Django的ORM中如何判斷查詢結果是否為空,判斷django中的orm為空
result= Booking.objects.filter()
方法一 .exists()
if result.exists():
print "QuerySet has Data"
else:
print "QuerySet is empty"
方法二 .count()==0
if result.count() == 0:
print "empty"
方法三
if result:
print "QuerySet has Data"
else:
print "QuerySet is empty"
總結:
QuerySet.exists() > QuerySet.count()==0 > QuerySet
2、模板中顯示資料庫內容的方法
a、建立資料庫
from django.db import models
from django.db import models
class Business(models.Model):
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32)
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32,db_index=True)
ip = models.GenericIPAddressField(protocol='both',db_index=True)
port = models.IntegerField()
business = models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)
business.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>業務線列表(物件)</h1>
<ul>
{% for row in v1 %}
<li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li>
{% endfor %}
</ul>
<h1>業務線列表(字典)</h1>
<ul>
{% for row2 in v2 %}
<li>{{ row2.id }}-{{ row2.caption }}</li>
{% endfor %}
</ul>
</body>
</html>
host.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>主機列表(物件)</h1>
<table border="1">
<tread>
<tr>
<th>主機ID</th>
<th>IP</th>
<th>埠</th>
<th>業務線名稱</th>
</tr>
</tread>
<tbody>
{% for row in v1 %}
<tr>
<td>{{ row.hostname }}</td>
<td>{{ row.ip }}</td>
<td>{{ row.port }}</td>
<td>{{ row.business.caption }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h1>主機列表(字典)</h1>
<table border="1">
<tread>
<tr>
<th>主機ID</th>
<th>主機名</th>
<th>業務線ID</th>
<th>業務線名稱</th>
</tr>
</tread>
<tbody>
{% for row in v2 %}
<tr>
<td>{{ row.nid }}</td>
<td>{{ row.hostname }}</td>
<td>{{ row.business__id }}</td>
<td>{{ row.business__caption }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h1>主機列表(元祖)</h1>
<table border="1">
<tread>
<tr>
<th>主機ID</th>
<th>主機名</th>
<th>業務線ID</th>
<th>業務線名稱</th>
</tr>
</tread>
<tbody>
{% for row in v3 %}
<tr>
<td>{{ row.0 }}</td>
<td>{{ row.1 }}</td>
<td>{{ row.2 }}</td>
<td>{{ row.3 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
from django.shortcuts import render,HttpResponse
from app01 import models
def business(request):
# 第一種方式(是個物件)
v1 = models.Business.objects.all()
# 第二種方式,只取id和caption(是個字典)
v2 = models.Business.objects.all().values('id','caption')
return render(request,'business.html',{'v1':v1,'v2':v2})
def host(request):
#總共三種方式,物件,字典,列表
v1 = models.Host.objects.all()
v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','business__id','business__caption')
v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','business__id','business__caption')
return render(request,'host.html',{'v1':v1,'v2':v2,'v3':v3})
釋出於 2019-07-20 11:33 Django(框架) Django-ORM
推薦閱讀
關於Django效能優化 你不可不知的基礎(主要針對ORM)
酷酷的運動圓一篇文章帶你瞭解Django ORM操作(高階篇)
來源:Python爬蟲與資料探勘 作者:Python進階者 前言上次兩篇基本學完的Django ORM各種操作,怎麼查,各種查。感興趣的小夥伴可以戳這兩篇文章學習下,一篇文章帶你瞭解Django ORM操作(進…
CDA資料...Django ORM Cookbook精選摘錄(下) 使用訊號和重寫save方法哪個好?
大江狗Django從入門到大作業:5-ORM操作
上一節涉及到對資料庫初步的操作,歡迎移步 koko可可:Django從入門到大作業:4-資料庫0. ORM(Object Relational Mapping)上一章解釋了一下,但沒有深入應用ORM,後臺也僅限於賬戶的操作…
koko可可5 條評論
寫下你的評論...- 曲中人02-11 感謝!
- 不想加班的戰鬥雞2021-12-29 太牛了,超用心的整理
-
狒狒2020-01-03
太牛逼了,比百度出來的詳細太多了!
- 狐狸老爹2019-09-13 非常感謝,雪中送炭
- 冰先生2019-07-24 感謝,作者,寫的非常細