Django的基本使用2
小生 Q Q:1770058260
-------謝謝您的參考,如有疑問,歡迎交流
本次主要收集了在django中經常使用到的配置.便於大家查詢
目錄:
- 漢化admin,時間格式化,指定statics.
- 註冊models,自定義admin.
- 初始化models,創建超級用戶.
- ORM.
- ORM的使用
一. 常用配置
-
漢化admin,時間格式化,指定statics.
漢化admin,指定時區
LANGUAGE_CODE = ‘zh_Hans‘
TIME_ZONE = ‘Asia/Bangkok‘格式化時間顯示
USE_L10N = False
DATETIME_FORMAT = ‘Y-m-d H:i:s‘
DATE_FORMAT = ‘Y-m-d‘指定static
STATIC_URL = ‘/static/‘
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"),
) -
註冊models,自定義admin
from app.models import *admin.site.site_header = ‘服務器續費信息‘ # 此處設置頁面顯示標題
admin.site.site_title = ‘服務器續費信息‘ # 此處設置頁面頭部標題@admin.register(TableName)
class TNAdmin(admin.ModelAdmin):
fields = (‘issue‘,‘start_date‘,‘applicant‘,‘result‘,‘receiver‘,‘end_date‘,‘memo‘) # 設置編輯界面顯示的字段
list_display = (‘number‘,‘issue‘,‘start_date‘,‘applicant‘,‘result‘,‘receiver‘,‘end_date‘) # 設置在列表中顯示的字段
search_fields = (‘start_date‘,) #增加一個搜索欄
empty_value_display = ‘未填寫‘ # 覆蓋空字段為短劃線
ordering = (‘-number‘,) # 設置默認排序字段,-為降序
list_editable = [‘result‘,] # 設置可編輯字段
list_display_links = (‘id‘, ‘caption‘) # 設置哪些字段可以點擊進入編輯界面
date_hierarchy = ‘start_date‘ # 詳細時間分層篩選
list_filter = (‘start_date‘,‘end_date‘,‘receiver‘,‘result‘) # 過濾器 -
初始化models,創建超級用戶.
python manage.py makemigrations
python manage.py migratepython manage.py createsuperuser
-
什麽是ORM
ORM,對象關系映射,是一個對應關系,用於實現面向對象編程語言裏不同類型系統的數據之間的轉換,換言之,就是用面向對象的方式去操作數據庫的創建表以及增刪改查等操作。優點:
1.1 ORM使得我們的通用數據庫交互變得簡單易行,而且完全不用考慮該死的SQL語句,快速開發,由此而來
1.2 可以避免一些新手程序要寫sql語句帶來的性能問題缺點:
1.3 性能有所犧牲,不過現在的各種ORM框架都在嘗試各種方法,比如緩存,延遲加載等來減輕這個問題
1.4 對於個別復雜查詢,ORM仍力不從心,為了解決這個問題,ORM一般也支持寫raw sql。
二. ORM的使用
2.1 創建表
創建單表
創建關聯表:foreignkey(通過外鍵關聯)
表之間的關系:
一對一
一對多
多對多
2.2 創建單表
# 表創建完之後需要生成,執行兩條命令
# python manage.py makemigrations
# python manage.py migrate
from django.db import models
class 表名(models.Model):
字段名 = models.字段屬性(屬性值)
def __str__(self): # 防止打印對象時,輸出內存地址
return self.<要打印的變量>
字段屬性:
字段名 = models.CharField(max_length=64)
CharField :較短的字符串
IntegerField :數字
ForeignKey :
ManyToManyField :
2.2.1 單表的增,建議使用create第二種
create方式一:
表名.object.create(
字段1=要插入的數據1,
字段2=要插入的數據2,
字段3=要插入的數據3,
)
create方法二:以字典的方式插入
表名.object.create(**{"字段1":"數據1"})
save方法一:
變量=表名(字段1="數據1")
變量.save()
save方法二:
變量=表名()
變量.字段="數據1"
變量.save()
2.2.3 單表的刪除
表名.objects.filter(條件).deleter()
2.2.3 單表的修改
update方法:filter調用的是一個集合,效率比save高
表名.objects.filter(條件1,條件2).update(字段=數據)
save方法(相當於重新賦值):get調用的是一個對象
變量 = 表名.objects.get(條件)
變量.字段=數據
變量.save()
2.2.4 單表的查詢
<1>查數據
變量 = models.表名.objects.filter(id=2)[0] # 取出過濾出id=2的,第一行
filter(**kwargs) :包含與所給篩選條件相匹配的對象
all() :查詢所有結果
變量 = models.表名.objects.filter(id=2).values("字段")
# 返回一個列表,列表中包含字典,字典裏面存放的是"字段:數據"
# [{"字段1":"數據1"},{"字段2":"數據2"}]
<2>查到數據後的操作,在.filter和.all的後面
exclude(**kwargs) :包含與所給篩選條件不匹配的對象
order_by(*field) :對查詢結果排序
# 正序: 變量 = models.表名.objects.order_by("id")
# 倒序: 變量 = models.表名.objects.order_by("-id")
reverse() :對查詢結果反向排序
distinct() :從返回結果中剔除重復記錄
values_list(*field) :與values()相似,返回一個元組序列
count() :返回數據庫中匹配查詢的對象數量
first() :返回第一條記錄
last() :返回最後一條記錄
exists() :如果QuerySet包含數據,就返回True,否則返回False
惰性機制:
表名.objects.all()或者.filter()等都只是返回一個QuerySet(查詢結果集對象),
它並不會馬上執行sql,而是當調用QuerySet的時候才執行。
QuerySet特點:
1. 可叠代
2. 可切片
objs = models.表名.objects.all()
#叠代
for obj in objs:
print("obj:",obj)
#切片
print(objs[1])
print(objs[1:4])
print(objs[::-1])
3. 多表
3.1 一對多(ForeignKey),比如 表1:"出版社" 和 表2:"書",一個出版社可以出多本書,外鍵要放在多裏面
class 出版社表(models.Model):
出版社名 = models.CharField(max_length=30)
出版社地址 = models.CharField(max_length=30)
class 書表(models.Model):
書名 = models.CharField(max_length=30)
出版社 = models.ForeignKey("出版社表")
# 對於外鍵,ForeignKey,在數據庫中,Django會自動將字段存為"出版社_id"
# 當有外鍵時需要插入數據,寫為
# 第一種插入方式
書表.objects.create (
書名 = "魯濱遜流浪記"
出版社_id = "1" // 直接插入
)
# 第二種插入方式
pub = models.出版社表.objects.filter(id=1) # 首先實例化一個對象
書表.objects.create (
書名 = "魯濱遜流浪記"
出版社 = pub[0] # 然後插入
)
3.2 多對多(ManyToManyField)
比如作者和書,一個作者可以寫作本書,一本書可以由多個作者完成,這時候外鍵放哪都行
class 書表(models.Model):
書名 = models.CharField(max_length=30)
作者 = models.ManyToManyField("作者表") # 自動創建第三張表
class 作者表(models.Model):
作者名 = models.CharField(max_length=64)
這時候會產生一個表,結構為:
id 書表_id 作者表_id
1 5 4
2 5 1
3 5 2
4 6 1
5 6 1
插入數據的方法:
# 給一本書添加兩個作者
作者1 = models.作者表.objects.get(id=3)
作者1 = models.作者表.objects.get(id=4)
書表 = models.書表.objects.filter(id=3)[0]
# 一下三種方式都可
書表.作者.add(作者1,作者2)
書表.作者.add(作者1)
書表.作者.add(作者2)
書表.作者.add(*[作者1,作者2])
執行完之後。映射表的內容為:
id 書表_id 作者表_id
1 3 3
2 3 4
第三張表可以自己創建:
class 書表(models.Model):
書名 = models.CharField(max_length=30)
作者 = models.ManyToManyField("作者表") # 自動創建第三張表
class 作者表(models.Model):
作者名 = models.CharField(max_length=64)
class 第三張表(models.Model):
書 = models.ForeignKey(書表)
作者 = models.ForeignKey(作者表)
class Meta: # 定義表的相關屬性
unique_together=["書","作者"] # 聯合唯一,根據需求定義
id 書_id 作者_id
1 3 3 # 為了避免這種情況出現,表在創建的時候要做一個聯合唯一的屬性
2 3 3 # 為了避免這種情況出現,表在創建的時候要做一個聯合唯一的屬性
3 3 4
3.3 一對一
OneToOne:一個通過兩個Foreignkey,unqiue=True
4. 查詢
4.1 對象查詢
通過將查詢到的數據賦予給一個變量,這就叫對象查詢
4.1.1 正向查找
# 需求:找到書所在出版社的城市,其中書是一個表,出版社是一個表,出版社裏面包括城市
# 其中,書表外鍵到了出版社表
obj = models.書表.objects.filter(書名="魯濱遜流浪記")[0]
obj.外鍵.城市 # 可以通過外鍵,調用另一個表的字段
4.1.2 反向查找
# 現在有一個出版社表,一個書表,外鍵在書表
# 現在需要將某個出版社出版的所有的書輸出
obj = models.出版社表.objects.filter(name="人民出版社")
obj.書表_set.all().values("書名") # 通過 "表名_set" 這種格式反向查找
4.2 雙下劃線之單表條件查詢
models.表1.objects.filter(id__lt=10,id__gt=1) # 獲取id大於1且小於10的值
models.表1.objects.filter(id__in=[11,22,33]) # 獲取id等於11/22/33的數據
models.表1.objects.exclude(id_in=[11,22,33]) # 不等於
models.表1.objects.filter(name__contains="ven") # 與sql的模糊查詢類似
models.表1.objects.filter(name__icontains="ven") # icontains大小寫不敏感
models.表1.objects.filter(id__range=[1,2]) # 範圍,bettwen and
startswith(以什麽開頭)、istartwith、endswith(以什麽結尾)、iendwith
4.3 雙下劃線之關聯表查詢
# 把所有書名叫魯濱遜流浪記的出版社打印
models.出版社表.objects.filter(書表__書名="魯濱遜流浪記").vaules("出版社名").distinct()
# 打印人民出版社出版的書
models.書表.objects.filter(出版社表__出版社名="人民出版社").values("書名")
# 打印出,出版魯濱遜流浪記的出版社
models.書表.objects.filter(書表__書名="魯濱遜流浪記").values("外鍵__出版社名")
4.4 聚合查詢和分組查詢,是一種聚合函數
from django.db.models import Avg,Min,Sum,Max
Avg,Min,Sum,Max 是聚合方法
<1> 聚合查詢
在最後查詢的結果集上進行操作,只有一個結果
aggregate(*args,**kwargs)
# 作者wangyi發表的書價格的一個平均值
書表.objects.all().aggregate(Avg(‘價格‘))
<2> 分組查詢
先根據條件把所有的結果進行一個分組,然後對每一個結果進行操作
annotate(*args,**kwargs)
# 查詢每一個作者出的書價格的總價格
書表.objects.values("作者表__作者名").annotate(Sum("price"))
4.5 F查詢和Q查詢
4.5.1 F 查詢,使用查詢條件的值,專門取對象中某列值的操作
from django.db.models import F,Q
# 給每本書增加20塊錢
models.書表.objects.all().update(價格=F(‘價格‘)+20) # 只支持數字
4.5.2 Q 查詢,用於封裝關鍵字查詢
之前的查詢都是單關鍵字查詢,也有用過雙關鍵字,但是是用逗號分隔,代表and;
可是如果我想用或呢,或者我想用or裏面包括and,例如: a and (b or (d and e))
from django.db.models import F,Q
如果這樣寫,這兩個語句的結果都是一樣的:
obj = models.書表.objects.filter(id=3)[0]
obj = models.書表.objects.filter(Q(id=3))[0]
示例Q查詢的多關鍵字查詢
obj = models.書表.objects.filter( Q(id=3) | Q(書名="魯濱遜流浪記") ) # 使用管道符"|"實現or方法
obj = models.書表.objects.filter( Q(價格__gt=50) & (Q(id=3) | Q(書名="魯濱遜流浪記")) ) # 價格大於50並且(id=3或者書名=魯濱遜流浪記的書)
obj = models.書表.objects.filter( Q(價格__gt=50) & (Q(id=3) | Q(書名="魯濱遜流浪記")) , 顏色="紅色" ) # 用普通查詢加Q查詢,普通查詢必須放在Q查詢後面(查詢(價格大於50並且(id=3或者書名=魯濱遜流浪記)並且顏色為紅色的書)
5. 註意,創建表的時候,為了防止返回內存參數,建議寫為如下樣式
class 書表(models.Model):
書名 = models.CharField(max_length=30)
作者 = models.ManyToManyField("作者表")
def __str__(self)
return self.書名 # 將需要返回的數據使用str方法返回
Django的基本使用2