A. django1.7部署到mod_wsgi進入admin的界面沒有css樣式,django自帶伺服器可以,怎麼解決
拷貝此文件夾:python的安裝路徑\Lib\site-packages\django\contrib\admin\static文件到項目裡面,在項目的setting文件中添加STATIC_DIRS=(這個文件夾所在的路徑)即可
B. 中國有哪幾種編程語言
目前比較流行的編程語言:
1、Ruby
Ruby於1993年2月24日開始編寫至1995年12月才正式公開發布,一種為簡單快捷面向對象編程而創的腳本語言,Ruby是一個語法像Smalltalk一樣完全面向對象、腳本執行、又有Perl強大的文字處理功能的編程語言。
C. Django 的最佳開發實踐有哪些
project結構
這里定義的是python開源項目目錄結構中的$PROJ_NAME目錄內的內容,需要與python開源項目目錄結構結合起來。
PROJ_NAME/
__init__.py 這幾個文件是django創建project所必須的,不做過多說明
manage.py
settings.py
urls.py
apps/ 即使是「小」工程,也建議分成多個app,每個app足夠簡單,只解決某一個方面的問題 (注1)
myapp1/
myapp2/
extra_apps/ 引用的其他app。
libs/ 載入第三方模塊,可以避免版本沖突,按照標準的site-packages管理(注2)
python*.*/指定python版本號
site-packages/
requirements.pip #pip的依賴說明文件
tests/ project級別的測試,對於每個app,還要有自己的測試代碼
static/ 靜態內容
css/
js/
images/
uploads/ 上傳文件所在目錄
templates/ 模板目錄,覆蓋app的模板
flatpages/
comments/
example/
app1/
app2/
templatetags/ tag目錄
注1:指定app載入,在settings.py中設置:
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'apps'))
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'extras'))
sys.path.insert(0, os.path.join(PROJECT_ROOT, 'libs'))
注2:自定義libs的載入,在settings.py中設置:
sys.path.insert(0, '/{{MY_LIB)}/site-packages/*****.egg')
sys.path.insert(0, '/{{MY_LIB}} /site-packages/')
app目錄結構
$APP_NAME/
tests/ app級別的測試代碼
models/ 注1
__init__.py
Amodels.py
Bmodels.py
templates/ 注2
templatetags/ tag目錄
注1:如果很好的控制app的規模,Model類數量少,可以使用慣用的models.py文件中, 否則將models做成一個package
接下來可以有兩種做法:
1. 在__init__.py中import所有的Model類
2. 指定Model的元類(Meta)的app_label
D. 中國那種編程語言最受公司歡迎
目前比較流行的編程語言:
1、Ruby
Ruby於1993年2月24日開始編寫至1995年12月才正式公開發布,一種為簡單快捷面向對象編程而創的腳本語言,Ruby是一個語法像Smalltalk一樣完全面向對象、腳本執行、又有Perl強大的文字處理功能的編程語言。
E. 怎麼Django標簽過濾
1.創建一個模板庫
使用模板過濾器的時候,直接把過濾器寫在app里,
例如:在app里新建一個templatetags的文件夾,這個目錄應當和 models.py 、 views.py 等處於同一層次。例如:
books/
__init__.py
models.py
templatetags/
views.py
在 templatetags 中創建兩個空文件:一個 __init__.py (告訴Python這是一個包含了Python代碼的包)和一個用來存放你自定義的標簽/過濾器定義的文件。第二個文件的名字稍後將用來載入標簽。例如,如果你的自定義標簽/過濾器在一個叫作 poll_extras.py 的文件中,你需要在模板中寫入如下內容: {% load poll_extras %}
{% load %}標簽檢查 INSTALLED_APPS 中的設置,僅允許載入已安裝的Django應用程序中的模板庫。
要成為有效的標簽庫,模塊必須包含一個模塊級的變數: register ,這是一個 template.Library 的實例。這個 template.Library 實例是包含所有已注冊的標簽及過濾器的數據結構。因此,在模塊的頂部位置插入下述代碼:
fromdjangoimport template
register = template.Library()
F. 學什麼編程語言比較好
我應該學什麼語言?這句話被問的很多,但是通常是不會得到答案的。每種語言都有一個相對固定的崇拜者群體,每次在論壇上有人比較一種語言的好壞,就會引發一場持久的戰爭。之所以發生這種情況,正是因為各種編譯語言之間的力量是均衡的,沒有哪一種語言是完美的,能夠「終結」其它的所有語言。即使像Linux下的幾種腳本語言那些看似長的很像的語言,也沒有誰被誰完全替代,大家和平共處了許多年,並且在各自的位置發揮著自己的長處。這里就我所了解的幾種語言和自己學習的經歷給新人一點建議,如果你有特殊的需求,比如工程或者數學,那可能需要一些特殊的語言來解決,比如Lisp或者Ada,這在該領域內基本上是無可替代的,那你也沒有什麼好迷惘的了。如果你只是一個剛剛准備進入編程這一行的學生,或者是一個想業余時間搞點自己的小東西的業余開發者,卻不知道哪種語言比較適合自己,就接著往下看吧。首先是C語言。幾乎所有的書和計算機專業都把C語言稱為語言中基礎的基礎,在大學里基本上都屬於必修課程,而且,現在還是我們國家計算機等級考試和程序員水平與資格考試的標准語言。C語言之所以有這樣的地位,是因為它最接近底層,最接近匯編語言和機器語言,最接近機器的思維方式,其它更高級的語言,最終也要按照它的那些基本邏輯來處理問題。所以,學好C語言可以更方便的以機器的模式思考問題。另外,C語言所涉及到的程序的順序結構循環結構和分支結構,還有整數字元串數組等變數,這些都是萬物之源,所有的編程語言都離不了。而且C語言有著嚴格的格式規范,不符合規范的寫法或者錯誤的類型定義,都會引起編譯錯誤,還有像if(a=1)這種常見錯誤,都可以讓人在使用C語言的過程中養成良好的編程風格和代碼規范。這些習慣在以後使用其它更寬松的語言的時候,會大大提高你的代碼質量。還有,因為C最接近底層,其代碼效率只有手工優化的匯編可以匹敵,在許多腳本語言裡面(比如Python)可以把一些大運算量的關鍵代碼用C來完成,從而獲得更高的執行效率。綜上所述,如果你真的想學好編程語言,C是一定要好好學的。但是新手學C語言通常會出現一個問題,就是除了寫個排序演算法,似乎根本想不出來C語言有什麼用。這是因為我們的教科書講C語言的時候,只講這些基本演算法,甚至連讀寫文件都不去講,更不用說圖形界面處理了和網路操作了,沒有這些知識,想寫一個真正的應用那是不可能的。不過,書上沒有不等於學不了,文件操作和網路操作的講解網路上有著大把的講解,(現在Windows下用這個人比較少了,但是講解Linux下C語言編程的書還是相當多的。)只要你隨便找幾篇文章看看,具備了這些基礎知識,寫一個自己的WEB伺服器並不難。在逐步增加功能完善功能的同時,你的C語言基本上就可以達到相當牛人的水平了。從0開始學習C的成本是比較高的,如果沒有明師(或者一本好書)的指點,某些概念想開竅也有些困難。但是你一旦突破了C語言這個障礙,再學習其它的語言,學習的曲線將會大為平坦。除了C語言以外的其它流行的高級語言,不管是編譯語言還是腳本語言,基本上都是面向對象的語言了,所以你要搞清楚面向對象的概念。真正適合理解面向對象的語言,以前是SmallTalk,它是完全面向對象的,但是這個語言在中國很少見,書也很難買,現在,你可以學Ruby。(Ruby的作者是日本人,因此在許多論壇上提到它的時候會被許多憤青跳出來亂罵,這種做法是極其愚蠢的),近年新出來的Linux發生版裡面都自帶了Ruby支持,這已經充分說明了它在Linux管理方面的地位。而Ruby On Rails這個名字,更成了Web2.0快速開發的代名詞。該語言借鑒了其它許多語言的特點,並且寫出了自己的特點。在Ruby里,所有的東西都是對象,包括一個數字,你可以調用-1.abs這樣的方法。一切都是對象,才能讓你真正的理解面向對象。一旦你掌握了Ruby的思想和面向對象的設計方法,那麼使用Ruby on rails來開發一個網站將變得極其輕松,因為該框架已經包裝了WEB開發中用到的前後台的功能,所有的資料庫讀寫都通過你的對象自身來完成,前台HTML的生成有著完整的模板系統,只要把美工給你的HTML代碼裡面的內容換成你的變數就OK了。如果你擁有了C語言的根本,和面向對象的思維方式,那麼,如果因為工作需要,要去學習Java或者C#,那都是相當簡單的事情。至於Perl和Python,本身跟Ruby的語法就比較接近(Perl要復雜一些,稍後再說)。但是目前你所學習的C語言和Ruby,都不適合用來開發Windows桌面程序,如果有這個需求,目前最簡單的語言應該就是C#或者VB.Net了。通過簡單的拖放控制項就可以擺出相當專業的軟體界面,而程序本身要實現的功能也無非就是本地的文件處理和資料庫處理,只要了解了該功能所在的命名空間和幾個基本的函數,再查閱一下MSDN,寫程序輕輕鬆鬆。(以前使用最廣的是VB6,不過現在Windows已經全面遷移到了.Net平台,已經基本沒有必要再去學習VB6了。)當然,如果你不喜歡.Net平台,還可以選擇Delphi或者C++。C++通常被認為是更高級的C,但是實際上它們的差別很大。而C++用來寫桌面程序,無非也就是調用一些已經被包裝好的處理窗體的函數而已。(C也可以調用,只是比較麻煩一些罷了。)Delphi的語法需要一段時間來適應,但是Delphi的開發工具跟Visual Studio一樣簡單,大部分操作拖放控制項就OK。如果是在Linux下面,也有不錯的C++的IDE和開發庫用來開發桌面程序。C++入門容易升級很難,沒有個三五年的潛心研究,是沒有辦法精通它的精髓的。但是既然你已經學到了這一步,那你應該已經很明白自己需要學哪些東西了,只要去找書,找好的源代碼來研究就行了。Java語言的崇拜者很多,不得不單獨拿出來說。Java語言的愛好者喜歡在語言層面把Java和C++相比,而不屑於跟C#來比較,而在企業開發架構方面(特別是B/S方面),又拿Java和.Net來做比較,因為C++缺乏這方面的應用。Java語言本身是非常干凈的,但是被各種各樣的包搞的比較混亂,新手進來容易摸不著頭腦,而且框架太多,又互不兼容,習慣了Struts開發方式的人員,很可能在換了一家公司的以後,雖然Java很熟練,但是卻不得不又要花很長的時間來研究學習和適應另一種開發框架。(.Net也在向這個趨勢發展了,而像Ruby on Rails這種框架,則保證了框架的統一性,程序員的學習成本降低,企業的培訓成本和維護也更低了。)Java通常被認為適合用來開發超大型的B/S項目,而一般的腳本語言則被認為只適合小型的項目開發,通常,這種問題都是由於開發工具的限制帶來的。.Net平台如果不是因為Visual Studio這樣方便而優秀的開發工具,不可能取得今天的成就。而大部分腳本語言則沒有這個優勢,缺少大型項目的管控能力,使得代碼量始終保持在一個比較低的水平。但是像Python這樣的代碼,可以憑借良好的代碼設計,模塊間鬆散耦合,做出極其靈活而且大型的項目(比如YouTube)。Perl語言在Linux的系統維護方面有著不可動搖的地位,大量的系統維護代碼都是Perl語言寫的(而且php流行之前,WEB的CGI基本上也是以Perl語言為主的)。Perl在文本處理方面有著強大的能力,其正則表達式的處理方式更是成了其它語言必須兼容的標准。正則表達式的學習難度比較高,要想達到靈活運用的水平,需要大量的練習。(但是如果只是要達到基本的通用就行的水平,那還是相當簡單的。)而在WEB開發方面還有一個重要的語言不可不提,那就是PHP。PHP出現的目標就是提供更方便的網站開發的能力,它的語法跟其它的腳本語言比如Perl/Python/Ruby都很接近,而且提供原生的Mysql資料庫支持,讀寫資料庫即簡單又高效,而且因為Apache的良好支持,才使得LAMP平台能夠與Java和.Net平台相抗衡,而且成為了小型項目首選的解決方案。至於SQL,我並沒有拿它當一門語言來算,它只是你在做資料庫編程的時候所需要的一種工具罷了,就跟調用其它的系統函數沒有什麼區別。簡單的SQL語法無非就是插入刪除選擇更新四種操作。處於同樣地位的還有HTML/CSS/Javascript,如果做WEB開發,這三種東西是必須要了解的,當然,前兩種你可以不必精通,因為有美工來負責,而JavaScript屬於完整的編程語言范疇,通常的美工是沒有辦法熟練掌握的,還是需要程序人員的搞定。但是Javascript的難度,在這個階段大概只有學習Ruby的十分之一了,想學,很快就可以掌握。(PS:Javascript也是一門易學難精的語言,好的JS框架全世界也就那麼幾個人能寫的出來,比如prototype,jquery,extjs)。程序語言多種多樣,但是編程的思想卻是不變的,而像設計模式、程序架構這種東西,都是語言無關的。一個開發項目,前階段的需求分析,項目分析,直到概要設計階段都是語言無關的,而項目設計期間使用的UML圖也做到了盡量抽象,和具體的實現語言無關。直到詳細設計和編碼的時候,才需要針對不同的語言的特點做些調整,而它們提供的功能則是完全一致的。作為一個好的程序員,需要的不是編碼的能力,而是需求分析和項目設計的能力,用哪種語言來實現則是可以隨機應變的,只要掌握了具體語言的學習方法,熟練掌握一門語言並不需要太長的時間。因此,在經過了最初的語言學習的階段之後,程序設計人員需要盡快的向下一個階段演變,對設計模式的學習和理解是一個長期的過程,需要大量經驗的積累,並經常的總結經驗,從經驗中歸納出自己常用的模式。作為程序員,還要有精益求精的態度,在時間允許的情況下,時常反思自己的作品,尋找更好的解決方案,在瀏覽網站學習的過程中,時刻以自己的項目為思考的對象,當發現更好的方法的時候,使用恰當的工具和方法來重構自己的項目。在這樣不斷進步的過程中,你就已經不再局限於一個普通的程序員了。只有C和C++沒有C+
可以先學C在學C++在學C#
這是一條不錯的路線~
想專業點的話的話先學C再C++再JAVA,C#,其餘的如VB,pascal跟著學就可以了
要是寫一些小程序的話C和VB是比較常用的,JAVA也可以,不過那是解釋型的。一般用在網上(寫網頁的還有html,asp,php等)。不過Java是比較新的語言,潛力很大,據說以後95%的程序會用它來寫,手機上的小游戲一般都是用它寫的。其實他用來寫小游戲也不錯,如robotcode之類,不需要很深的專業知識,比較容易上手。
一般會C跟Java就差不多了,C是必須要學的,經典且強大,C++基本可由Java代替
昨晚封了兩個網段的IP,124.115.0.*和124.115.1.*,終於解決了伺服器這兩天來的經常莫名其妙的停止響應的問題。網站的流量現在並不是很大,而且大部分頁面的邏輯也很簡單,但是最近兩天經常出現網站沒有反應,一直顯示在等待,打不開頁面。遠程登錄伺服器速度也非常慢,基本上很難操作,查看進程發現django多出了很多子進程,這說明有些進程堵塞在那裡,無法返回所以啟動了新的子進程。給mysql資料庫啟用了slow-log以後,日誌里經常會出現一些簡單的查詢語句,直接把語句放到mysql客戶端里去執行,速度卻相當快,估計是因為mysql並發量太大,導致這些簡單的語句也無法順利執行,所以把所有的網站頁面都堵死了。後來查看網站的訪問日誌,好傢伙,已經1.5個G的日誌了,這個樣子在這種速度下也沒辦法查看,於是清空了日誌,稍等了一會,很快就超過了100K,打開一看,sosospider的名字映入眼簾。N多個來自不同IP的soso蜘蛛同時抓取portal頁面,即便文章頁已經啟用了緩存也不起作用。於是趕緊停了網站,到lighttpd設置里封了soso的這兩個網段,順便封了網易有道的一個蜘蛛IP,雖然並發沒有soso這么大,但是每隔幾條日誌里就有一條是網易有道的。拜託騰訊soso的開發兄弟們,不會寫程序別亂寫,寫出這種程序來還放出來咬人,會給人家造成切實的經濟損失的。有趣的是,在soso裡面搜索soso蜘蛛,出來的全是soso蜘蛛因為亂抓網站被站長封殺的新聞,soso還真是大公無私啊,絕對沒有屏蔽自己的負面新聞。Django的最佳系統結構
Django也用了一段時間了,寫了兩三個小網站,但是始終感覺自己寫出來的站點目錄和功能的安排還是比較混亂,很難達到讓自己滿意的效果,更不要說令人賞心悅目了。尤其是,當你需要開發下一個網站的時候,雖然感覺用戶部分的功能(注冊/登錄/忘記密碼/修改用戶信息)所有的網站是通用的,但是想復用現有網站的這個功能卻相當困難,居然笨到只能把模板文件/Model/View挨個復制過去再修改,實在是難登大雅之堂。於是狠命的研究了一些文章,終於算是找到了點前人的經驗之談,大概的總結如下:項目文件manage.py/urls.py/settings.py盡量少的改動(當然,不改動也是不可能的),setting.py裡面需要設置資料庫的相關信息,還有模板目錄之類的,模板目錄是可以使用相對目錄的(使用os.path),很可惜,我沒有測試成功,在lighttpd下面它仍然使用相對目錄來搜索模板,所以總是報錯,但是我找到了另一種解決方案。
setting.py裡面有一個配置選項TEMPLATE_LOADERS。默認情況下它使用兩種載入機制,第一種是文件系統方式,即使用下面配置的TEMPLATE_DIRS目錄,在裡面尋找模板文件,如果沒有找到,第二種是app模式,它會在INSTALLED_APPS所標識的已安裝的App下面尋找templates目錄,並在其中尋找模板文件。而這個第二種,跟TEMPLATE_DIRS是無關的。因此,只要注釋掉第一行,TEMPLATE_DIRS這個選項就可以留空了。然後,在任意一個App目錄下面建一個templates目錄,把模板文件扔進去就OK了。當然,最佳方案是,每個Apps下面放它自己用到的模板文件。這樣,以後將這個App放進其它的項目的時候,你不需要做任何設置,模板這一塊就已經正常工作了。
然後是Urls,在每個App下面添加它自己的urls.py文件,在裡面設定它所用到的url映射,然後在項目級的urls.py裡面使用include方式載入各個App的url配置就可以了。但是這樣有一個要求,就是這個App要使用統一的目錄前綴,比如用戶相關的Url都以user/開頭。(我不知道是不是必須這樣,但是目前我所掌握的知識,只能這樣了。)
通過這兩個改動,已經將App和項目的耦合性降到了最低,現在如果要重用一個App,比如用戶部分,只要把user目錄拷到另一個項目,在settings中安裝這個App,在urls.py中include這個App的urls,就OK了。至少裡面所有的功能都是正常可用的。(當然,模板文件可能需要針對新的項目做些改動,但是如果你的模板設計規則是相同的,那麼只要在新項目的framework里使用相同的內容,而使用另一種不同的style文件就可以了。)花了不少時間把理財易的代碼整理了一遍,整理了一下功能的組織,把用戶部分/留言板/日記本/投票以及站內信/好友/圈子(這三個功能在理財易中沒有開放)全部建成單獨的App,並分離了Urls和模板,雖然導致項目目錄下面的子目錄多了很多,但是每個目錄的功能都簡單明白了很多,可以很方便的添加或者移除某個App,比如圈子或者站內信,只要在配置文件中安裝該App,相應的頁面上添加鏈接,該功能就變得馬上可用了。最基本的理論就是這樣,剩下還有一些高級技巧,比如:每個App下面都可以建一個叫sql的目錄,裡面建立對應於model名稱的sql文件,那麼,在執行了syncdb命令安裝該App以後,這個SQL文件就會被自動調用,可以用來往分類表裡插入系統默認的分類,或者往用戶表裡插入一條最高許可權的初始用戶等等。
每個App下面都可以建一個叫templatetags的目錄,在裡面添加template tags和filters,大家互不幹擾。
每個App下面都可以建一個叫tests的子目錄,裡面放一些單元測試的代碼,就可以直接對該App進行單元測試。
每個App下面都可以建一個叫management.py的文件,裡面可以放任意的Python函數,並給該函數添加事件介面聲明,比如dispatcher.connect(my_syncdb_func, signal=signals.post_syncdb),這樣就可以在App安裝完成的時候執行任意的功能。(注意,是在添加了任何一個App以後都會被調用到,而不止是自己被安裝以後。)
還有,每個App下面的views.py不是必須的,你可以按照自己的需求把函數拆解到多個python文件中,只要在urls.py中引用了正確的類名就可以了。這對於一個功能比較多的App是相當有用的。
有了這些屬性的幫忙,基本上你可以對自己的項目文件做出各種適合自己的調整,並且仍然保持項目結構的優雅,並且,對於程序的執行效能是完全沒有影響的。希望這篇文章對於Django的用戶起到一點幫助。
G. 第10節、案例-客戶關系管理系統之增刪改查筆記
第10節、案例-客戶關系管理系統之增刪改查筆記
一、建立模型
1、導入模型
fromdjango.dbimportmodels
2、創建學生表
classStudent(models.Model):# 學生表
name=models.CharField(max_length=20)
age=models.SmallIntegerField()
sex=models.SmallIntegerField(default=1)
qq=models.CharField(max_length=20,unique=True)
phone=models.CharField(max_length=20,unique=True)
c_time=models.DateTimeField(verbose_name='創建時間',auto_now_add=True)
e_time=models.DateTimeField(verbose_name='修改時間',auto_now=True)
grade=models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True)
is_delete=models.BooleanField(default=False)# 一般實際開發過程中,我們不會直接刪除數據,而是給數據加上is_delete欄位,來標記數據的狀態。
def__str__(self):
return'%s-%s-%s'%(self.name,self.age,self.sex)
3、創建學生詳情表
classStudentDetail(models.Model):#學生詳情表
num=models.CharField('身份證',max_length=40,unique=True)
college=models.CharField('畢業學校',max_length=20,default='')
student=models.OneToOneField('Student',on_delete=models.CASCADE,related_name='detail')
def__str__(self):
return'%s-%s'%(self.num,self.college)
4、創建班級表
classGrade(models.Model):# 班級表
name=models.CharField('班級名稱',max_length=20)
num=models.CharField('班期',max_length=20)
def__str__(self):
return'%s-%s'%(self.name,self.num)
5、創建課程表
classCourse(models.Model):# 課程表
name=models.CharField('課程名稱',max_length=20)
student=models.ManyToManyField('Student',through='Enroll')
def__str__(self):
return'%s'%self.name
6、創建學生表與課程表的中間表
classEnroll(models.Model):# 課程與學生多對多中間表
student=models.ForeignKey('Student',on_delete=models.CASCADE)
course=models.ForeignKey('Course',on_delete=models.CASCADE)
pay=models.FloatField('繳費金額',default=0)
c_time=models.DateTimeField(verbose_name='創建時間',auto_now_add=True)
def__str__(self):
return'%s'%self.pay
##
二、增刪改查功能實現
1、index頁面視圖函數
fromdjango.shortcutsimportrender,redirect,reverse
fromdjango.httpimportHttpResponse
fromstudent.modelsimportStudent,Grade,StudentDetail
fromdjango.db.modelsimportQ
fromdjango.core.paginatorimportPaginator
# Create your views here.
defindex(request):
section='學生列表'
search=request.POST.get('search','').strip()# 接收從html的form表單傳過來的參數
ifsearch:
ifsearch.isdigit():# 如果是數值類型則
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字元型
sts=Student.objects.filter(name=search,is_delete=False)# 則和名字匹配
else:# search都沒有匹配到則查詢所有學生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
})
2、學生刪除頁視圖
defstudent_delete(request,pk):
student=Student.objects.get(pk=pk)# 查詢id為pk的學生
student.is_delete=True# 將is_delete標記為True,
student.save()# 保存
returnredirect(reverse('student:index'))
3、學生詳情頁視圖
defstudent_detail(request,pk):
section='學生詳情'
grades=Grade.objects.all()# 查詢所有班級
sts=Student.objects.get(pk=pk)# 獲取當前id為pk的學生信息
grade=Grade.objects.get(pk=sts.grade_id)# 查詢指定學生的班級
detail=StudentDetail.objects.get(student=sts)# 查詢指定學生的詳情
returnrender(request,'student/student_detail.html',context={
'section':section,
'grades':grades,
'sts':sts,
'grade':grade,
'detail':detail,
})
4、添加頁視圖函數
defstudent_add(request):
section='添加學生信息'
grades=Grade.objects.all()# 獲取所有的班級
ifrequest.method=='GET':
returnrender(request,'student/student_detail.html',context={
'section':section,
'grades':grades,
})
ifrequest.method=='POST':
# 獲取班級信息
grade_id=request.POST.get('grade')# 獲取前端傳回來的grade.id
try:
grade=Grade.objects.get(pk=grade_id)
except:
grade=None
# 獲取學生信息姓名、年齡、性別、qq、電話
data= {
'name':request.POST.get('name'),
'age':request.POST.get('age'),
'sex':request.POST.get('sex'),
'qq':request.POST.get('qq'),
'phone':request.POST.get('phone'),
'grade':grade#表關聯,在student中
}
student=Student.objects.create(**data)
# 獲取學生詳情信息
StudentDetail.objects.create(
num=request.POST.get('num'),
college=request.POST.get('college'),
student=student# 表關聯
)
returnredirect(reverse('student:index'))
5、修改學生信息頁視圖函數
defstudent_edit(request,pk):
section='修改學生信息'
sts=Student.objects.get(pk=pk)# 查詢id為pk的學生
grade=Grade.objects.get(pk=sts.grade_id)# 查詢指定學生的班級
detail=StudentDetail.objects.get(student=sts)# 查詢指定學生的詳情
ifrequest.method=='GET':
returnrender(request,'student/student_detail.html',context={
'section':section,
'sts':sts,
'grade':grade,
'detail':detail,
})
ifrequest.method=='POST':
# 獲取班級信息
grade_id=request.POST.get('grade')# 獲取前端傳回來的grade
try:
grade=Grade.objects.get(pk=grade_id)# 獲取學生的班級
except:
grade=None
# 獲取學生信息並修改
student=Student.objects.get(pk=pk)
student.name=request.POST.get('name')
student.age=request.POST.get('age')
student.sex=request.POST.get('sex')
student.qq=request.POST.get('qq')
student.phone=request.POST.get('phone')
student.grade=grade# 表關聯
# 獲取學生詳情
try:
detail=student.detail# 表關聯,關聯表在student
except:
detail=StudentDetail()
detail.student=student# 表關聯,關聯表在detail
detail.num=request.POST.get('num')
detail.college=request.POST.get('college')
detail.save()# 保存
student.save()# 保存
returnredirect(reverse('student:index'))
三、分頁功能實現
1、對主頁分頁方法一
1.1主頁的視圖函數
defindex(request):
section='學生列表'
search=request.POST.get('search','').strip()# 接收從html的form表單傳過來的參數
ifsearch:
ifsearch.isdigit():# 如果是數值類型則
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字元型
sts=Student.objects.filter(name=search,is_delete=False)# 則和名字匹配
else:# search都沒有匹配到則查詢所有學生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
# 分頁
total_num=sts.count()# 總的數據量
per_page=int(request.GET.get('per_page',5))# 每頁默認條數為5
page=int(request.GET.get('page',1))# 當前頁面默認為第1頁
p=Paginator(sts,per_page,allow_empty_first_page=True)
sts=p.get_page(page)# 每頁顯示的數據
total_page=p.num_pages# 總的頁面數
page_list=p.page_range# 獲取頁面范圍
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
'total_num':total_num,
'total_page':total_page,
'page':page,
'per_page':per_page,
'page_list':page_list,
})
1.2、html中頁碼的設置
<navaria-label="Page navigation"style="display: inline-block">
<ulclass="pagination">
<li{%ifpage==1%}class="disabled"{%endif%}>
<ahref="{% if page > 1 %}{% url 'student:index' %}?page={{ page|add:-1 }}&per_page={{ per_page }}{% else %}{% url 'student:index' %}?page={{ page }}&per_page={{ per_page }}{% endif %}"aria-label="Previous">
<spanaria-hidden="true">上一頁</span>
</a>
</li>
{% for i in page_list %}
<li{%ifpage==i%}class="active"{%endif%}><ahref="{{ request.path }}?page={{ i }}&per_page={{ per_page }}">{{ i }}</a></li>
{% endfor %}
<li{%ifpage==total_page%}class="disabled"{%endif%}>
<ahref="{% if page < total_page %}{% url 'student:index' %}?page={{ page|add:1 }}&per_page={{ per_page }}{% else %}{% url 'student:index' %}?page={{ page }}&per_page={{ per_page }}{% endif %}"aria-label="Next">
<spanaria-hidden="true">下一頁</span>
</a>
</li>
</ul>
</nav>
<!-- Single button -->
<divclass="btn-group"style="display: inline-block; margin-top: -68px">
<buttontype="button"class="btn btn-default dropdown-toggle"data-toggle="dropdown"aria-haspopup="true"aria-expanded="false">
{{ per_page }}條/頁<spanclass="caret"></span>
</button>
<ulclass="dropdown-menu">
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 5 ">5條/頁</a></li>
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 10 ">10條/頁</a></li>
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 15 ">15條/頁</a></li>
<li><ahref="{% url 'student:index' %}?page={{ page}}&per_page= 20 ">20條/頁</a></li>
</ul>
</div>
2、對主頁分頁方法二(利用包含標簽)
2.1、index中的視圖函數
defindex(request):
section='學生列表'
search=request.POST.get('search','').strip()# 接收從html的form表單傳過來的參數
ifsearch:
ifsearch.isdigit():# 如果是數值類型則
sts=Student.objects.filter(Q(qq=search)|Q(phone=search),is_delete=False)# 用qq和phone去匹配
else:# 如果是字元型
sts=Student.objects.filter(name=search,is_delete=False)# 則和名字匹配
else:# search都沒有匹配到則查詢所有學生
sts=Student.objects.filter(is_delete=False)
sts=sts.order_by('-c_time')# 排序
# 分頁
total_num=sts.count()# 總的數據量
per_page=int(request.GET.get('per_page',5))# 每頁默認條數為5
page=int(request.GET.get('page',1))# 當前頁面默認為第1頁
p=Paginator(sts,per_page,allow_empty_first_page=True)
sts=p.get_page(page)# 每頁顯示的數據
total_page=p.num_pages# 總的頁面數
page_list=p.page_range# 獲取頁面范圍
returnrender(request,'student/index.html',context={
'sts':sts,
'section':section,
'search':search,
'total_num':total_num,
'total_page':total_page,
'page':page,
'per_page':per_page,
'page_list':page_list,
})
2.2、在templatetags文件夾中創建student_custormer_tags.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# author:cyb time:2019/5/25 23:34
fromdjangoimporttemplate
register=template.Library()
@register.inclusion_tag('student/paginitor.html',takes_context=True)
defpagination_html(context):# 誰引用就導入誰的context
total_page=context['total_page']# 總的頁面數
page=context['page']# 顯示第幾頁的數據
page_list=context['page_list']# 頁面范圍
per_page=context['per_page']# 每頁條數
'''
假設現在total_page = 6
兩種頁碼控制方法:
當num = 1 # 當前頁面左右各有幾頁
上一頁 1 2 3 下一頁
上一頁 4 5 6 下一頁
上一頁 1 2 下一頁
上一頁 5 6 下一頁
當num = 2 # 當前頁面左右各有幾頁
上一頁 1 2 3 下一頁
上一頁 1 2 3 4 下一頁
上一頁 1 2 3 4 5 下一頁
上一頁 2 3 4 5 6 下一頁
上一頁 4 5 6 下一頁
'''
page_list= []
num=2
# 1、左邊 + 當前頁顯示的頁碼列表
# 1.1、左邊不夠顯示時,頁碼范圍1到當前頁
ifpage-num<=0:
foriinrange(1,page+1):
page_list.append(i)
else:# 左邊夠顯示時,頁碼范圍page-num到當前頁
foriinrange(page-num,page+1):
page_list.append(i)
# 2、右邊 + 當前頁顯示的頁碼列表
# 2.1、右邊不夠顯示時,頁碼范圍當前頁到total_page
ifpage+num>=total_page:
foriinrange(page+1,total_page+1):
page_list.append(i)
# 2.2、右邊夠顯示時,頁碼范圍(當前頁+1)到(當前頁+num)
else:
foriinrange(page+1,page+num):
page_list.append(i)
return{
'total_page':total_page,
'page':page,
'page_list':page_list,
'per_page':per_page
}
2.3、在app中新建一個包含標簽渲染模板paginitor.html
<ulclass="pagination">
<li{%ifpage==1%}class="disabled"{%endif%}>
<a{%ifpage>1 %} href="{% url 'student:index' %}?page={{ page|add:'-1' }}&per_page={{ per_page }}{% endif %}" aria-label="Previous">
<spanaria-hidden="true">«</span>
</a>
</li>
{% for page_num in page_list %}
<li{%ifpage_num==page%}class="active"{%endif%}><ahref="{{ request.path }}?page={{ page_num }}&per_page={{ per_page }}">{{ page_num }}</a></li>
{% endfor %}
<li{%ifpage==total_page%}class="disabled"{%endif%}>
<a{%ifpage< total_page %} href="{{ request.path }}?page={{ page|add:'1' }}&per_page={{ per_page }}{% endif %}" aria-label="Next">
<spanaria-hidden="true">»</span>
</a>
</li>
</ul>
2.4、在index.html中導入後在對應位置引用
1、導入:{% load student_customer_tags %}
2、引用:
<nav aria-label="Page navigation" style="display: inline-block">
{% pagination_html %}
</nav>
四、頁面展示
1、主頁展示
2、添加頁展示
3、修改頁展示