1. python + django 多表聯合查詢方法求教
先讓我們回憶一下在第五章里的關於書本(book)的數據模型:1fromdjango.dbimportmodelsclassPublisher(models.Model):name=models.CharField(max_length=30)address=models.CharField(max_length=50)city=models.CharField(max_length=60)state_province=models.CharField(max_length=30)country=models.CharField(max_length=50)website=models.URLField()def__unicode__(self):returnself.nameclassAuthor(models.Model):first_name=models.CharField(max_length=30)last_name=models.CharField(max_length=40)email=models.EmailField()def__unicode__(self):returnu'%s%s'%(self.first_name,self.last_name)classBook(models.Model):title=models.CharField(max_length=100)authors=models.ManyToManyField(Author)publisher=models.ForeignKey(Publisher)publication_date=models.DateField()def__unicode__(self):returnself.title如我們在第5章的講解,獲取資料庫對象的特定欄位的值只需直接使用屬性。例如,要確定ID為50的書本的標題,我們這樣做:>>>frommysite.books.modelsimportBook>>>b=Book.objects.get(id=50)>>>b.titleu'TheDjangoBook'但是,在之前有一件我們沒提及到的是表現為ForeignKey或ManyToManyField的關聯對象欄位,它們的作用稍有不同。訪問外鍵(ForeignKey)值當你獲取一個ForeignKey欄位時,你會得到相關的數據模型對象。例如:>>>b=Book.objects.get(id=50)>>>b.publisher>>>b.publisher.websiteu'http://www.apress.com/'對於用``ForeignKey``來定義的關系來說,在關系的另一端也能反向的追溯回來,只不過由於不對稱性的關系而稍有不同。通過一個``publisher``對象,直接獲取books,用publisher.book_set.all(),如下:>>>p=Publisher.objects.get(name='ApressPublishing')>>>p.book_set.all()[,,]實際上,book_set只是一個QuerySet(參考第5章的介紹),所以它可以像QuerySet一樣,能實現數據過濾和分切,例如:1>>>p=Publisher.objects.get(name='ApressPublishing')>>>p.book_set.filter(name__icontains='django')[,]屬性名稱book_set是由模型名稱的小寫(如book)加_set組成的。訪問多對多值(Many-to-ManyValues)多對多和外鍵工作方式相同,只不過我們處理的是QuerySet而不是模型實例。例如,這里是如何查看書籍的作者:>>>b=Book.objects.get(id=50)>>>b.authors.all()[,]>>>b.authors.filter(first_name='Adrian')[]>>>b.authors.filter(first_name='Adam')[]反向查詢也可以。要查看一個作者的所有書籍,使用author.book_set,就如這樣:>>>a=Author.objects.get(first_name='Adrian',last_name='Holovaty')>>>a.book_set.all()[,]這里,就像使用ForeignKey欄位一樣,屬性名book_set是在數據模型(model)名後追加_set。更改資料庫模式(DatabaseSchema)3在我們在第5章介紹syncdb這個命令時,我們注意到syncdb僅僅創建資料庫里還沒有的表,它並不對你數據模型的修改進行同步,也不處理數據模型的刪除。如果你新增或修改數據模型里的欄位,或是刪除了一個數據模型,你需要手動在資料庫里進行相應的修改。這段將解釋了具體怎麼做:當處理模型修改的時候,將Django的資料庫層的工作流程銘記於心是很重要的。如果模型包含一個未曾在資料庫里建立的欄位,Django會報出錯信息。當你第一次用Django的資料庫API請求表中不存在的欄位時會導致錯誤(就是說,它會在運行時出錯,而不是編譯時)。3Django不關心資料庫表中是否存在未在模型中定義的列。Django不關心資料庫中是否存在未被模型表示的表格。1改變模型的模式架構意味著需要按照順序更改Python代碼和資料庫。添加欄位1當要向一個產品設置表(或者說是model)添加一個欄位的時候,要使用的技巧是利用Django不關心表裡是否包含model里所沒有的列的特性。策略就是現在資料庫里加入欄位,然後同步Django的模型以包含新欄位。3然而這里有一個雞生蛋蛋生雞的問題,由於要想了解新增列的SQL語句,你需要使用Django的manage.pysqlall命令進行查看,而這又需要欄位已經在模型里存在了。(注意:你並不是非得使用與Django相同的SQL語句創建新的欄位,但是這樣做確實是一個好主意,它能讓一切都保持同步。)3這個雞-蛋的問題的解決方法是在開發者環境里而不是發布環境里實現這個變化。(你正使用的是測試/開發環境,對吧?)下面是具體的實施步驟。首先,進入開發環境(也就是說,不是在發布環境里):在你的模型里添加欄位。運行manage.pysqlall[yourapp]來測試模型新的CREATETABLE語句。注意為新欄位的列定義。開啟你的資料庫的交互命令界面(比如,psql或mysql,或者可以使用manage.pydbshell)。執行ALTERTABLE語句來添加新列。使用Python的manage.pyshell,通過導入模型和選中表單(例如,MyModel.objects.all()[:5])來驗證新的欄位是否被正確的添加,如果一切順利,所有的語句都不會報錯。3然後在你的產品伺服器上再實施一遍這些步驟。啟動資料庫的交互界面。5執行在開發環境步驟中,第三步的ALTERTABLE語句。將新的欄位加入到模型中。如果你使用了某種版本控制工具,並且在第一步中,已經提交了你在開發環境上的修改,現在,可以在生產環境中更新你的代碼了(例如,如果你使用Subversion,執行svnupdate。重新啟動Webserver,使修改生效。讓我們實踐下,比如添加一個num_pages欄位到第五章中Book模型。首先,我們會把開發環境中的模型改成如下形式:classBook(models.Model):title=models.CharField(max_length=100)authors=models.ManyToManyField(Author)publisher=models.ForeignKey(Publisher)publication_date=models.DateField()**num_pages=models.IntegerField(blank=True,null=True)**def__unicode__(self):returnself.title
2. Django怎麼算列的總數
這個看在哪裡算了。如果是在伺服器端算,和一般的python運算是一樣的啊。或者直接執行SQL語句。
3. python + django 多表聯合查詢方法求教
先讓我們回憶一下在第五章里的關於書本(book)的數據模型:
1
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
def __unicode__(self):
return self.title
如我們在第5章的講解,獲取資料庫對象的特定欄位的值只需直接使用屬性。 例如,要確定ID為50的書本的標題,我們這樣做:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
但是,在之前有一件我們沒提及到的是表現為ForeignKey 或 ManyToManyField的關聯對象欄位,它們的作用稍有不同。
訪問外鍵(Foreign Key)值
當你獲取一個ForeignKey 欄位時,你會得到相關的數據模型對象。 例如:
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
對於用`` ForeignKey``
來定義的關系來說,在關系的另一端也能反向的追溯回來,只不過由於不對稱性的關系而稍有不同。 通過一個`` publisher`` 對象,直接獲取
books ,用 publisher.book_set.all() ,如下:
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
實際上,book_set 只是一個 QuerySet(參考第5章的介紹),所以它可以像QuerySet一樣,能實現數據過濾和分切,例如:
1
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.filter(name__icontains='django')
[<Book: The Django Book>, <Book: Pro Django>]
屬性名稱book_set是由模型名稱的小寫(如book)加_set組成的。
訪問多對多值(Many-to-Many Values)
多對多和外鍵工作方式相同,只不過我們處理的是QuerySet而不是模型實例。 例如,這里是如何查看書籍的作者:
>>> b = Book.objects.get(id=50)
>>> b.authors.all()
[<Author: Adrian Holovaty>, <Author: Jacob Kaplan-Moss>]
>>> b.authors.filter(first_name='Adrian')
[<Author: Adrian Holovaty>]
>>> b.authors.filter(first_name='Adam')
[]
反向查詢也可以。 要查看一個作者的所有書籍,使用author.book_set ,就如這樣:
>>> a = Author.objects.get(first_name='Adrian', last_name='Holovaty')
>>> a.book_set.all()
[<Book: The Django Book>, <Book: Adrian's Other Book>]
這里,就像使用 ForeignKey欄位一樣,屬性名book_set是在數據模型(model)名後追加_set。
更改資料庫模式(Database Schema)
3
在我們在第5章介紹 syncdb 這個命令時, 我們注意到 syncdb僅僅創建資料庫里還沒有的表,它 並不 對你數據模型的修改進行同步,也不處理數據模型的刪除。 如果你新增或修改數據模型里的欄位,或是刪除了一個數據模型,你需要手動在資料庫里進行相應的修改。 這段將解釋了具體怎麼做:
當處理模型修改的時候,將Django的資料庫層的工作流程銘記於心是很重要的。
如果模型包含一個未曾在資料庫里建立的欄位,Django會報出錯信息。 當你第一次用Django的資料庫API請求表中不存在的欄位時會導致錯誤(就是說,它會在運行時出錯,而不是編譯時)。
3
Django不關心資料庫表中是否存在未在模型中定義的列。
Django不關心資料庫中是否存在未被模型表示的表格。
1
改變模型的模式架構意味著需要按照順序更改Python代碼和資料庫。
添加欄位
1
當要向一個產品設置表(或者說是model)添加一個欄位的時候,要使用的技巧是利用Django不關心表裡是否包含model里所沒有的列的特性。 策略就是現在資料庫里加入欄位,然後同步Django的模型以包含新欄位。
3
然而 這里有一個雞生蛋蛋生雞的問題 ,由於要想了解新增列的SQL語句,你需要使用Django的
manage.py sqlall命令進行查看 ,而這又需要欄位已經在模型里存在了。 (注意:你並 不是非得使用與Django相同的SQL語句創建新的欄位,但是這樣做確實是一個好主意 ,它能讓一切都保持同步。)
3
這個雞-蛋的問題的解決方法是在開發者環境里而不是發布環境里實現這個變化。 (你正使用的是測試/開發環境,對吧?)下面是具體的實施步驟。
首先,進入開發環境(也就是說,不是在發布環境里):
在你的模型里添加欄位。
運行 manage.py sqlall [yourapp] 來測試模型新的 CREATE TABLE 語句。 注意為新欄位的列定義。
開啟你的資料庫的交互命令界面(比如, psql 或mysql , 或者可以使用
manage.py dbshell )。 執行 ALTER TABLE 語句來添加新列。
使用Python的manage.py shell,通過導入模型和選中表單(例如,
MyModel.objects.all()[:5] )來驗證新的欄位是否被正確的添加 ,如果一切順利,所有的語句都不會報錯。
3
然後在你的產品伺服器上再實施一遍這些步驟。
啟動資料庫的交互界面。
5
執行在開發環境步驟中,第三步的ALTER TABLE語句。
將新的欄位加入到模型中。 如果你使用了某種版本控制工具,並且在第一步中,已經提交了你在開發環境上的修改,現在,可以在生產環境中更新你的代碼了(例如,如果你使用Subversion,執行svn update。
重新啟動Web server,使修改生效。
讓我們實踐下,比如添加一個num_pages欄位到第五章中Book模型。首先,我們會把開發環境中的模型改成如下形式:
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
**num_pages = models.IntegerField(blank=True, null=True)**
def __unicode__(self):
return self.title
4. django 獲取數據表中 有多少條數據
Django 擁有自己的ORM模塊。
通俗來講其過程如下:
在Django中寫Python 代碼
將Python代碼通過ORM模塊轉換成SQL語句
通過類似pymysql等資料庫操作模塊,使用SQL語句,前往資料庫訪問數據
上述過程的反方向
獲取Python格式的數據
5. django 過濾器 什麼意思
關於django過濾器,
過濾器,變數的顯示形式的改變
一、形式:小寫
{{ name | lower }}
二、串聯:先轉義文本到HTML,再轉換每行到 <p> 標簽
{{ my_text|escape|linebreaks }}
三、過濾器的參數
顯示前30個字
{{ bio | truncatewords:"30" }}
格式化
{{ pub_date | date:"F j, Y" }}
過濾器列表
{{ 123|add:"5" }} 給value加上一個數值
{{ "AB'CD"|addslashes }} 單引號加上轉義號,一般用於輸出到javascript中
{{ "abcd"|capfirst }} 第一個字母大寫
{{ "abcd"|center:"50" }} 輸出指定長度的字元串,並把值對中
{{ "123spam456spam789"|cut:"spam" }} 查找刪除指定字元串
{{ value|date:"F j, Y" }} 格式化日期
{{ value|default:"(N/A)" }} 值不存在,使用指定值
{{ value|default_if_none:"(N/A)" }} 值是None,使用指定值
{{ 列表變數|dictsort:"數字" }} 排序從小到大
{{ 列表變數|dictsortreversed:"數字" }} 排序從大到小
{% if 92|divisibleby:"2" %} 判斷是否整除指定數字
{{ string|escape }} 轉換為html實體
{{ 21984124|filesizeformat }} 以1024為基數,計算最大值,保留1位小數,增加可讀性
{{ list|first }} 返回列表第一個元素
{{ "ik23hr&jqwh"|fix_ampersands }} &轉為&
{{ 13.414121241|floatformat }} 保留1位小數,可為負數,幾種形式
{{ 13.414121241|floatformat:"2" }} 保留2位小數
{{ 23456 |get_digit:"1" }} 從個位數開始截取指定位置的1個數字
{{ list|join:", " }} 用指定分隔符連接列表
{{ list|length }} 返回列表個數
{% if 列表|length_is:"3" %} 列表個數是否指定數值
{{ "ABCD"|linebreaks }} 用新行用<p> 、 <br /> 標記包裹
{{ "ABCD"|linebreaksbr }} 用新行用<br /> 標記包裹
{{ 變數|linenumbers }} 為變數中每一行加上行號
{{ "abcd"|ljust:"50" }} 把字元串在指定寬度中對左,其它用空格填充
{{ "ABCD"|lower }} 小寫
{% for i in "1abc1"|make_list %}ABCDE,{% endfor %} 把字元串或數字的字元個數作為一個列表
{{ "abcdefghijklmnopqrstuvwxyz"|phone2numeric }} 把字元轉為可以對應的數字??
{{ 列表或數字|pluralize }} 單詞的復數形式,如列表字元串個數大於1,返回s,否則返回空串
{{ 列表或數字|pluralize:"es" }} 指定es
{{ 列表或數字|pluralize:"y,ies" }} 指定ies替換為y
{{ object|pprint }} 顯示一個對象的值
{{ 列表|random }} 返回列表的隨機一項
{{ string|removetags:"br p div" }} 刪除字元串中指定html標記
{{ string|rjust:"50" }} 把字元串在指定寬度中對右,其它用空格填充
{{ 列表|slice:":2" }} 切片
{{ string|slugify }} 字元串中留下減號和下劃線,其它符號刪除,空格用減號替換
{{ 3|stringformat:"02i" }} 字元串格式,使用Python的字元串格式語法
{{ "E<A>A</A>B<C>C</C>D"|striptags }} 剝去[X]HTML語法標記
{{ 時間變數|time:"P" }} 日期的時間部分格式
{{ datetime|timesince }} 給定日期到現在過去了多少時間
{{ datetime|timesince:"other_datetime" }} 兩日期間過去了多少時間
{{ datetime|timeuntil }} 給定日期到現在過去了多少時間,與上面的區別在於2日期的前後位置。
{{ datetime|timeuntil:"other_datetime" }} 兩日期間過去了多少時間
{{ "abdsadf"|title }} 首字母大寫
{{ "A B C D E F"|truncatewords:"3" }} 截取指定個數的單詞
{{ "<a>1<a>1<a>1</a></a></a>22<a>1</a>"|truncatewords_html:"2" }} 截取指定個數的html標記,並補完整
<ul>{{ list|unordered_list }}</ul> 多重嵌套列表展現為html的無序列表
{{ string|upper }} 全部大寫
<a href="{{ link|urlencode }}">linkage</a> url編碼
{{ string|urlize }} 將URLs由純文本變為可點擊的鏈接。(沒有實驗成功)
{{ string|urlizetrunc:"30" }} 同上,多個截取字元數。(同樣沒有實驗成功)
{{ "B C D E F"|wordcount }} 單詞數
{{ "a b c d e f g h i j k"|wordwrap:"5" }} 每指定數量的字元就插入回車符
{{ boolean|yesno:"Yes,No,Perhaps" }} 對三種值的返回字元串,對應是 非空,空,None
6. django查詢數據量總數問題
AttributeCount = UrlList.objects.filter(url_source_id__in=[2,3,5,6,7,8]).count()
return render_to_response('main.html', {'AttributeCount':AttributeCount})
這樣試試吧
7. django 如何用formset 顯示資料庫里的經過 過濾的數據用戶資料和修改資料
formset是一個困惑的東西。用好了可以簡化代碼,減少template和view的工作量。不過初學的時候,可以自己直接寫html代碼更直觀些。
formset似乎與資料庫並沒有直接的關系。查詢資料庫的class.objects.query里,使用select語句什麼都能過濾。當然也可以用get , all ,filter等函數,在函數的入口裡加入等於的過濾條件,這個過濾比較的簡單的。
8. django先exclude 再filter
Model.objects.exclude(xxxx=xx).filter(xxxx=xx)
這樣就可以了,可以連貫操作的。。。
filter裡面也可以多個filter(xxxx=xx,aaa=aa,bbb=bb)
9. 如何有效的遍歷django的QuerySet
最近做了一個小的需求,在django模型中通過前台頁面的表單的提交
(post),後台對post的參數進行解析,通過models模型查詢MySQL,將數據結構進行加工,返回到前台頁面進行展示。由於對django中
QuerySet特性的不熟悉,所以測試過程中發現了很多問題。
開始的階段沒有遇到什麼問題,我們舉例,在models有一張員工表
employee,對應的表結構中,postion列表示員工職位,前台post過來的參數賦給position,加上入職時間、離職時間,查詢操作通過
models.filter(position=params)完成,獲取的員工信息內容由QuerySet和當前展示頁與每頁展示的記錄數進行簡單的計
算,返回給前台頁面進行渲染展示。編碼如下:
1 def get_employees(position, start, end):
2 return employee.objects.filter(alert_time__lt=end,alert_time__gt=start).filter(position__in=position)
3
4
5 @login_required
6 def show(request):
7 if not validate(request):
8 return render_to_response('none.html',
9 context_instance=RequestContext(request, 'msg':'params error')
10 )
11
12 position = request.REQUEST.get('position')
13 time_range = request.REQUEST.get('time')
14 start, end = time_range[0], time_range[1]
15
16 num_per_page, page_num = get_num(request)
17 all_employees = get_employees(position, start, end)
18 # 根據當前頁與每頁展示的記錄數,取到正確的記錄
19 employees = employees_events[(page_num-1)*num_per_page:page_num*num_per_page]
20
21 return render_to_response('show_employees.html',
22 context_instance=RequestContext(
23 request,
24 'employees': employees,
25 'num_per_page': num_per_page,
26 'page_num':page_num,
27 'page_options' : [50, 100, 200]
28 )
29 )
運行之後可以正確的對所查詢的員工信息進行展示,並且查詢速度很快。
employee表中存放著不同職位的員工信息,不同類型的詳細內容也不相同,假設employees有一列名為infomation,存儲的是員工的詳
細信息,infomation = {'age': 33, 'gender': 'male', 'nationality': 'German',
'degree': 'doctor', 'motto': 'just do
it'},現在的需求是要展示出分類更細的員工信息,前台頁面除了post職位、入職離職時間外,還會對infomation中的內容進行篩選,這里以查
詢中國籍的設計師為例,在之前的代碼基礎上,需要做一些修改。員工信息表employee存放於MySQL中,而MySQL為ORM資料庫,它並未提供類
似mongodb一樣更為強大的聚合函數,所以這里不能通過objects提供的方法進行filter,一次性將所需的數據獲取出來,那麼需要對type
進行過濾後的數據,進行二次遍歷,通過information來確定當前記錄是否需要返回展示,在展示過程中,需要根據num_per_page和
page_num計算出需要展示數據起始以及終止位置。
1 def get_employees(position, start, end):
2 return employee.objects.filter(alert_time__lt=end,alert_time__gt=start).filter(position__in=position)
3
4
5 def filter_with_nation(all_employees, nationality, num_per_page, page_num):
6 result = []
7
8 pos = (page_num-1)*num_per_page
9 cnt = 0
10 start = False
11 for employee in all_employees:
12 info = json.loads(employee.information)
13 if info.nationality != nationality:
14 continue
15
16 # 獲取的數據可能並不是首頁,所以需要先跳過前n-1頁
17 if cnt == pos:
18 if start:
19 break
20 cnt = 0
21 pos = num_per_page
22 start = True
23
24 if start:
25 result.append(employee)
26
27 return employee
28
29
30 @login_required
31 def show(request):
32 if not validate(request):
33 return render_to_response('none.html',
34 context_instance=RequestContext(request, 'msg':'params error')
35 )
36
37 position = request.REQUEST.get('position')
38 time_range = request.REQUEST.get('time')
39 start, end = time_range[0], time_range[1]
40
41 num_per_page, page_num = get_num(request)
42 all_employees = get_employees(position, start, end)
43
44 nationality = request.REQUEST.get('nationality')
45
46 employees = filter_with_nation(all_employees, num_per_page, page_num)
47
48 return render_to_response('show_employees.html',
49 context_instance=RequestContext(
50 request,
51 'employees': employees,
52 'num_per_page': num_per_page,
53 'page_num':page_num,
54 'page_options' : [50, 100, 200]
55 )
56 )
當編碼完成之後,在數據employee表數據很小的情況下測試並未發現問
題,而當數據量非常大,並且查詢的數據很少時,代碼運行非常耗時。我們設想,這是一家規模很大的跨國公司,同時人員的流動量也很大,所以employee
表的數據量很龐大,而這里一些來自於小國家的員工並不多,比如需要查詢國籍為梵蒂岡的員工時,前台頁面進入了無盡的等待狀態。同時,監控進程的內存信息,
發現進程的內存一直在增長。毫無疑問,問題出現在filter_with_nation這個函數中,這里逐條遍歷了employee中的數據,並且對每條
數據進行了解析,這並不是高效的做法。
在網上查閱了相關資料,了解到:
1 Django的queryset是惰性的,使用filter語句進行查詢,實際上並沒有運行任何的要真正從資料庫獲得數據
2 只要你查詢的時候才真正的操作資料庫。會導致執行查詢的操作有:對QuerySet進行遍歷queryset,切片,序列化,對 QuerySet 應用 list()、len()方法,還有if語句
3 當第一次進入循環並且對QuerySet進行遍歷時,Django從資料庫中獲取數據,在它返回任何可遍歷的數據之前,會在內存中為每一條數據創建實例,而這有可能會導致內存溢出。
上面的原來很好的解釋了代碼所造成的現象。那麼如何進行優化是個問題,網上有
說到當QuerySet非常巨大時,為避免將它們一次裝入內存,可以使用迭代器iterator()來處理,但對上面的代碼進行修改,遍歷時使用
employee.iterator(),而結果和之前一樣,內存持續增長,前台頁面等待,對此的解釋是:using iterator()
will save you some memory by not storing the result of the cache
internally (though not necessarily on PostgreSQL!); but will still
retrieve the whole objects from the database。
這里我們知道不能一次性對QuerySet中所有的記錄進行遍歷,那麼只能對
QuerySet進行切片,每次取一個chunk_size的大小,遍歷這部分數據,然後進行累加,當達到需要的數目時,返回滿足的對象列表,這里修改下
filter_with_nation函數:
1 def filter_with_nation(all_employees, nationality, num_per_page, page_num):
2 result = []
3
4 pos = (page_num-1)*num_per_page
5 cnt = 0
6 start_pos = 0
7 start = False
8 while True:
9 employees = all_employees[start_pos:start_pos+num_per_page]
10 start_pos += num_per_page
11
12 for employee in employees:
13 info = json.loads(employee.infomation)
14 if info.nationality != nationality:
15 continue
16
17 if cnt == pos:
18 if start:
19 break
20 cnt = 0
21 pos = num_per_page
22 start = True
23
24 if start:
25 result.append(opt)
26
27 cnt += 1
28
29 if cnt == num_per_page or not events:
30 break
31
32 return result
運行上述代碼時,查詢的速度更快,內存也沒有明顯的增長,得到效果不錯的優
化。這篇文章初衷在於記錄自己對django中queryset的理解和使用,而對於文中的例子,其實正常業務中,如果需要記錄員工詳細的信息,最好對
employee表進行擴充,或者建立一個字表,存放詳細信息,而不是將所有信息存放入一個欄位中,避免在查詢時的二次解析。