先記下最坑的地方吧。關於django呼叫原生語句rawqueryset的一些問題。
官方文件上有一段話是這樣寫的:
警告雖然rawqueryset
可以像普通的queryset
一樣迭代,rawqueryset
並沒有實現可以在 queryset
上使用的所有方法。例如,__bool__()
和__len__()
在rawqueryset
中沒有被定義,所以所有rawqueryset
轉化為布林值的結果都是true
。rawqueryset
中沒有實現他們的原因是,在沒有內部快取的情況下會導致效能下降,而且增加內部快取不向後相容。
在些被坑了好久。因為對django不夠熟悉的原因,在多表聯查、資料分頁上被這個的物件坑的不要不要的。
我的view裡關於資料查詢的一段**是這樣寫的。
因為devices的model裡沒有定義dataroomname這個名稱的字段,當時想到的只能是通過多表聯查,同時查詢 dataroom表和devices表的資料然後顯示出來。
#獲取rawqueryset結果的len值
defget_len(rawqueryset):
def__len__
(self):
params = ["""
'%s'
""" % p for p in
self.params]
sql = '
select count(*) from (
' + (rawqueryset.raw_query % tuple(params)) + '
) b;
'cursor =connection.cursor()
cursor.execute(sql)
row =cursor.fetchone()
return
row[0]
return
__len__
defdevicelist(request):
user = request.session["
userdata
"]["
user"]
totalsec = len(devices.objects.filter(devicetype=3))
totalnet = len(devices.objects.filter(devicetype=2))
totalserver = len(devices.objects.filter(devicetype=1))
totaldevices =len(devices.objects.all())
page_num = 1 #
給頁碼乙個初始賦值
if request.method == "
get"
and request.get.get("
page"):
page_num = request.get.get("
page")
page_num =int(page_num)
page_numnext = page_num+1page_numlast = page_num-1
#機房select下拉框
dataroom =importform(request.post)
#查詢語句
sql = "
select users_devices.basemodel_ptr_id,users_devices.sn,users_devices.cabinetid,users_devices.devicemap,users_devices.company,users_devices.model,users_devices.produceip,users_devices.updatetime,users_dataroom.dataroomname from users_dataroom,users_devices where users_dataroom.basemodel_ptr_id = users_devices.dataroomid"#
獲取多表聯查結果
devicedata =devices.objects.raw(sql)
#獲取結果表長度並強行定義給rawqueryset物件以實現前端分面
setattr(type(devicedata), '
__len__
', get_len(devicedata))
page_total = len(devicedata)/10
if page_total !=int(page_total):
page_total += 1page_total =int(page_total)
page_list = range(1,page_total+1)#
確定頁碼
在此算是把django原生語句的用法用了個遍。最關鍵的是還會出現一些小bug。比如用了
setattr(type(devicedata), '__len__', get_len(devicedata))之後。另乙個頁面的rawqueryset查詢的前端顯示也會愛到影響。。。。
解決方法:(多表聯查什麼的理論上都可以通過這個實現)
model中定義函式直接通過queryset獲取。。還是用orm吧。。。原生的sql不到成不得已,還是不要用。。。
models.py
classcabinet(basemodel):
cabinetname = models.charfield(max_length=32, verbose_name="
機櫃名稱")
dataroomid = models.integerfield(verbose_name="
機房id")
capacity = models.charfield(max_length=32,verbose_name="
機櫃容量")
#ablecapacity = models.charfield(max_length=32,verbose_name="機櫃可用量")
cabinetdes = models.charfield(max_length=64,verbose_name="
機櫃描述")
#獲取裝置數目
defgetdevicescout(self):
return len(devices.objects.filter(cabinetid=self.basemodel_ptr_id))
#獲取機房名稱
defgetdataroomname(self):
return dataroom.objects.get(basemodel_ptr_id=self.dataroomid).dataroomname
#計算剩餘可用容量
defablecapcity(self):
deviceuse =0
for device in devices.objects.filter(cabinetid=self.basemodel_ptr_id):
devicespace = int(device.devicesize) + 1deviceuse = deviceuse+devicespace
ablecap = int(self.capacity)-deviceuse
return ablecap
view.pycabinetdata =cabinet.objects.all()
html:
class="
first
">
"checkbox
" style="
margin-top: 0
"/>
class="
description
">}
class="
description
">}
class="
description
">}
class="
description
">}
class="
description
">}
回不到開掛的過去,只有前行的探索
有段時間突然在想如果現在讓我穿越回童年,讓我重新過一遍整個讀書生涯。但是,除了身體變小之外,大腦和思想仍然是目前的狀態,哇靠,那我一定是開掛的狀態,我一定能稱霸我們學校了,當然不是因為這些知識已經學過的關係,而是因為我現在已經知道了學習的目的,方法,我能在乙個更高的層面上來看待讀書這個事。所謂的認真...
CMDB與網路的聯動 老段的修煉人生
網路裝置相關關係 伺服器連線埠 網路裝置包含埠 網路裝置包含板卡 板卡包含埠 虛擬交換機連線物理交換機埠 虛擬交換機包含物理網絡卡 虛擬網路連線虛擬交換機 虛擬網絡卡連線虛擬網路 虛擬分布式交換機連線物理交換機埠 虛擬分布式交換機包含物理網絡卡 虛擬網路連線虛擬分布式交換機 ci的屬性 型別 子型別...
PWA的探索與應用
本文由雲 社群發表 傳統的web網頁存在以下幾個問題 2016 年google i o 大會上提出乙個 next web generation 的概念。pwa是在傳統web應用的基礎上,結合manifest和service worker,完善web應用的一些能力,比如 pwa 站點部署的 manif...