天天看點

Django 基礎(二),Model連表、Form自定義錯誤資訊、Ajax操作

一、Model連表操作

一對一和一對多

表結構如下:

1

2

3

4

5

6

7

8

9

10

<code>class</code> <code>user_type(models.Model):</code>

<code>    </code><code>name </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>50</code><code>)</code>

<code>class</code> <code>user(models.Model):</code>

<code>    </code><code>username </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>50</code><code>)</code>

<code>    </code><code>password </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>50</code><code>)</code>

<code>    </code><code>email </code><code>=</code> <code>models.EmailField()</code>

<code>    </code><code>usertype </code><code>=</code> <code>models.ForeignKey(user_type)</code>

<code>    </code> 

<code>user.objects.</code><code>filter</code><code>(usertype__id </code><code>=</code> <code>1</code><code>).values(</code><code>'username'</code><code>)</code>

示例

<code># 查詢user表中,使用者類型為管理者的所有使用者</code>

<code>data </code><code>=</code> <code>user.objects.</code><code>filter</code><code>(usertype__name </code><code>=</code> <code>'管理者'</code><code>)</code>

<code># 取單字段(比如隻取username字段)</code>

<code>data </code><code>=</code> <code>user.objects.</code><code>filter</code><code>(usertype__name </code><code>=</code> <code>'管理者'</code><code>).values(</code><code>'username'</code><code>)</code>

<code># 大于條件</code>

<code>data </code><code>=</code> <code>user.objects.</code><code>filter</code><code>(usertype__id__gt</code><code>=</code><code>3</code><code>)</code>

這裡通過__(雙下劃線)表示連表查詢,比如usertype__name相當于操作到了user_type表的name字段。

多對多關系

<code>class</code> <code>groups(models.Model):</code>

<code>    </code><code>gname </code><code>=</code> <code>models.CharField(max_length</code><code>=</code><code>255</code><code>)</code>

<code>    </code><code>guser </code><code>=</code> <code>models.ManyToManyField(</code><code>'user'</code><code>)</code>

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

<code>user_obj </code><code>=</code> <code>models.user.objects.get(name</code><code>=</code><code>u</code><code>'tuchao'</code><code>)</code>

<code>user_objs </code><code>=</code> <code>models.user.objects.</code><code>all</code><code>()</code>

<code> </code> 

<code>group_obj </code><code>=</code> <code>models.groups.objects.get(gname</code><code>=</code><code>'dev'</code><code>)</code>

<code>group_objs </code><code>=</code> <code>models.groups.objects.</code><code>all</code><code>()</code>

<code># 添加資料</code>

<code>#group_obj.guser.add(user_obj)</code>

<code>#group_obj.guser.add.add(*user_objs)</code>

<code># 删除資料</code>

<code>#group_obj.guser.remove(user_obj)</code>

<code>#group_obj.guser.remove(*user_objs)</code>

<code># 這裡有點繞,使用者表的對象.組表的名稱(與使用者相關系的表其中有定義與使用者表的多對多關系)_set.add(組表的對象)</code>

<code>#user_obj.groups_set.add(group_obj)</code>

<code>#user_obj.groups_set.add(*group_objs)</code>

<code>#user_obj.groups_set.remove(group_obj)</code>

<code>#user_obj.groups_set.remove(*group_objs)</code>

<code># 擷取資料</code>

<code>#print group_obj.guser.all()</code>

<code>#print group_obj.guser.all().filter(id=1)</code>

<code>#print user_obj.groups_set.all()</code>

<code>#print user_obj.groups_set.all().filter(gname='tuchao')</code>

<code>#print user_obj.groups_set.all().filter(gname='tyz')</code>

<code># 使用MySQL事務的方式完成多對多關系的資料插入,當使用事務方式的時候,在同一個事務中的語句要麼全部執行成功,要麼一個都不會執行,保證了資料的完整性。</code>

<code>#導入相關庫</code>

<code>from</code> <code>django.db </code><code>import</code> <code>connection,transaction</code>

<code>try</code><code>:</code>

<code>    </code><code>''' 啟動事務 '''</code>

<code>    </code><code>with transaction.atomic():</code>

<code>    </code><code>''' 先給使用者資訊表插入資料 '''</code>

<code>        </code><code>user.objects.create(username</code><code>=</code><code>username,password</code><code>=</code><code>password,realname</code><code>=</code><code>realname,email</code><code>=</code><code>email,ugid</code><code>=</code><code>group_id)</code>

<code>    </code><code>''' 然後通過使用者名擷取該條記錄的資料,取出對應關系的ID值插入到關系表 '''</code>    

<code>        </code><code>d1 </code><code>=</code> <code>user.objects.get(username</code><code>=</code><code>username)</code>

<code>        </code><code>uuid </code><code>=</code> <code>d1.uid</code>

<code>        </code><code>ugid </code><code>=</code> <code>d1.ugid</code>

<code>        </code><code>userandgroup.objects.create(gid</code><code>=</code><code>ugid,uid</code><code>=</code><code>uuid)</code>

<code>except</code> <code>Exception,err:</code>

<code>    </code><code>print</code> <code>(err)</code>

二、Form 建立自定義錯誤資訊

forms.py的檔案

<code>class</code> <code>RegisterForm(forms.Form):</code>

<code>    </code><code>username </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.TextInput(attrs</code><code>=</code><code>{</code><code>'class'</code><code>:</code><code>'user_name'</code><code>,</code><code>'placeholder'</code><code>:</code><code>'使用者名'</code><code>}),help_text</code><code>=</code><code>'100 characters max.'</code><code>)</code>

<code>    </code><code>password </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.PasswordInput(attrs</code><code>=</code><code>{</code><code>'class'</code><code>:</code><code>'pwd'</code><code>,</code><code>'placeholder'</code><code>:</code><code>'密碼'</code><code>}))</code>

<code>    </code><code>real_name </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.TextInput(attrs</code><code>=</code><code>{</code><code>'placeholder'</code><code>:</code><code>'真實姓名'</code><code>}))</code>

<code>    </code><code>email </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.EmailInput(attrs</code><code>=</code><code>{</code><code>'placeholder'</code><code>:</code><code>'Email'</code><code>}))</code>

<code>    </code><code>gender </code><code>=</code> <code>forms.BooleanField()</code>

<code># 這裡的'placeholder':'使用者名' 是input裡面的參數。 如: &lt;input name="hostname" placeholder="hostname" /&gt;</code>

<code>class</code> <code>AdminHostAdd(forms.Form):</code>

<code>    </code><code>othername </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.TextInput(attrs</code><code>=</code><code>{</code><code>'class'</code><code>:</code><code>'othername'</code><code>}),error_messages</code><code>=</code><code>{</code><code>'required'</code><code>:(</code><code>'業務名不能為空'</code><code>),</code><code>'invalid'</code><code>:</code><code>'業務名格式錯誤'</code><code>})</code>

<code>    </code><code>hostname </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.TextInput(attrs</code><code>=</code><code>{</code><code>'class'</code><code>:</code><code>'hostname'</code><code>}),error_messages</code><code>=</code><code>{</code><code>'required'</code><code>:(</code><code>'主機名不能為空'</code><code>),</code><code>'invalid'</code><code>:</code><code>'主機名格式錯誤'</code><code>})</code>

<code>    </code><code>hardconfig </code><code>=</code> <code>forms.CharField(widget</code><code>=</code><code>forms.TextInput(attrs</code><code>=</code><code>{</code><code>'class'</code><code>:</code><code>'hardconfig'</code><code>}),error_messages</code><code>=</code><code>{</code><code>'required'</code><code>:(</code><code>'硬體配置資訊不能為空'</code><code>)})</code>

<code>    </code><code>wip </code><code>=</code> <code>forms.IPAddressField(error_messages</code><code>=</code><code>{</code><code>'required'</code><code>:(</code><code>'外網IP不能為空'</code><code>),</code><code>'invalid'</code><code>:</code><code>'IP格式錯誤'</code><code>})</code>

<code>    </code><code>lip </code><code>=</code> <code>forms.IPAddressField(error_messages</code><code>=</code><code>{</code><code>'required'</code><code>:(</code><code>'内網IP不能為空'</code><code>),</code><code>'invalid'</code><code>:</code><code>'IP格式錯誤'</code><code>})</code>

<code># error_messages:required對應的是當送出内容為空所提示的資訊,invalid則表示送出的資料格式錯誤所提示的資訊。       </code>

<code># 在頁面中輸出自定義錯誤資訊</code>

<code># 在功能函數中截取的部分代碼,擷取自定義錯誤資訊</code>

<code>ret </code><code>=</code> <code>{</code><code>'data'</code><code>:</code><code>None</code><code>,</code><code>'error'</code><code>:</code><code>'None'</code><code>}</code>

<code>ret[</code><code>'data'</code><code>] </code><code>=</code> <code>form</code>

<code>firstmessage </code><code>=</code> <code>form.errors.as_data()</code>

<code># 将擷取的錯誤資訊傳給字典,key為error</code>

<code>ret[</code><code>'error'</code><code>] </code><code>=</code> <code>firstmessage.values()[</code><code>0</code><code>][</code><code>0</code><code>].messages[</code><code>0</code><code>]</code>

<code># 在輸出資訊的時候傳回頁面和字典</code>

<code>return</code> <code>render_to_response(</code><code>'admin-host-add.html'</code><code>,ret)</code>

<code># 在Html中擷取傳回的字典資料</code>

<code>&lt;span </code><code>class</code><code>=</code><code>"hostaddstatus"</code><code>&gt;{{ error }}&lt;</code><code>/</code><code>span&gt;</code>

三、學習使用Ajax

Ajax的基本文法

<code>/* 首先引入Jquery  */</code>

<code>&lt;script src=</code><code>"/static/assets/js/jquery-1.12.0.js"</code><code>&gt;&lt;/script&gt;</code>

<code>&lt;script type=</code><code>"text/javascript"</code><code>&gt;</code>

<code>function</code> <code>DoAjax(){</code>

<code>    </code><code>/* 擷取標明元素的資料 */</code>

<code>    </code><code>var</code> <code>temp = $(</code><code>'#text01'</code><code>).val();</code>

<code>    </code><code>$.ajax({</code>

<code>       </code><code>/* 送出請求的url */</code>  

<code>        </code><code>url:</code><code>'/ops01/ad/'</code><code>,</code>

<code>      </code><code>/* 送出請求的方式 */</code>    

<code>        </code><code>type:</code><code>'POST'</code><code>,</code>

<code>      </code><code>/* 傳回的資料,key:value */</code>  

<code>        </code><code>data:{data:temp},</code>

<code>      </code><code>/* 請求成功所執行的方法 */</code>

<code>        </code><code>success:</code><code>function</code><code>(arg){</code>

<code>            </code><code>console.log(</code><code>'success'</code><code>);</code>

<code>        </code><code>},</code>

<code>      </code><code>/* 請求失敗所執行的方法 */</code>

<code>        </code><code>error:</code><code>function</code><code>(){</code>

<code>            </code><code>console.log(</code><code>'failed'</code><code>)</code>

<code>        </code><code>}</code>

<code>    </code><code>});</code>

<code>}</code>

<code>&lt;/script&gt;</code>

功能實戰

實作登陸頁面在沒有登陸的情況下檢測使用者名是否存在,然後通過Ajax實作密碼錯誤檢測和登陸跳轉。

<code># Python 後端功能代碼實作</code>

<code>#!/usr/local/python27/bin/python2.7</code>

<code># coding=utf8</code>

<code># noinspection PyUnresolvedReferences</code>

<code>from</code> <code>django.shortcuts </code><code>import</code> <code>render</code>

<code>from</code> <code>ops01.forms </code><code>import</code> <code>RegisterForm,AdminHostAdd,CreateGroups</code>

<code>from</code> <code>django.http </code><code>import</code> <code>HttpResponse</code>

<code>from</code> <code>django.shortcuts </code><code>import</code> <code>render_to_response</code>

<code>from</code> <code>ops01.models </code><code>import</code> <code>*</code>

<code>import</code> <code>json</code>

<code>def</code> <code>Login(request):</code>

<code>    </code><code>if</code> <code>request.method </code><code>=</code><code>=</code> <code>'POST'</code><code>:</code>

<code>        </code><code>username </code><code>=</code> <code>request.POST.get(</code><code>'u'</code><code>,</code><code>None</code><code>)</code>

<code>        </code><code>password </code><code>=</code> <code>request.POST.get(</code><code>'p'</code><code>,</code><code>None</code><code>)</code>

<code>        </code><code>code </code><code>=</code> <code>request.POST.get(</code><code>'s'</code><code>,</code><code>None</code><code>)</code>

<code>        </code><code>print</code><code>(username,password,code)</code>

<code>        </code><code>data </code><code>=</code> <code>{</code><code>'statuscode'</code><code>: </code><code>0</code><code>, </code><code>'status'</code><code>: </code><code>'ok'</code><code>}</code>

<code>''' 當code=0 時表示檢查使用者名是否存在,當code=1 時表示嘗試登陸'''</code>

<code>        </code><code>if</code> <code>code </code><code>=</code><code>=</code> <code>'0'</code><code>:</code>

<code>            </code><code>un </code><code>=</code> <code>user.objects.</code><code>filter</code><code>(username</code><code>=</code><code>username)</code>

<code>            </code><code>if</code> <code>un:</code>

<code>                </code><code>return</code> <code>HttpResponse(json.dumps(data))</code>

<code>            </code><code>else</code><code>:</code>

<code>                </code><code>data[</code><code>'statuscode'</code><code>] </code><code>=</code> <code>1</code>

<code>                </code><code>data[</code><code>'status'</code><code>] </code><code>=</code> <code>'failed'</code>

<code>        </code><code>else</code><code>:</code>

<code>            </code><code>data </code><code>=</code> <code>un.values()[</code><code>0</code><code>]</code>

<code>            </code><code>print</code> <code>data.get(</code><code>'password'</code><code>)</code>

<code>            </code><code>if</code> <code>data.get(</code><code>'password'</code><code>) </code><code>=</code><code>=</code> <code>password:</code>

<code>                </code><code>data </code><code>=</code> <code>{</code><code>'statuscode'</code><code>: </code><code>0</code><code>, </code><code>'status'</code><code>: </code><code>'ok'</code><code>}</code>

<code>                </code><code>''' 傳回一個json格式的字典資料 '''</code>

<code>    </code><code>return</code> <code>render_to_response(</code><code>'login.html'</code><code>,{})</code>

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

<code>/* 前端javascript代碼實作  */</code>

<code>$(</code><code>function</code><code>(){</code>

<code>     </code><code>$(</code><code>'#email'</code><code>).blur(</code><code>function</code><code>(){</code>

<code>            </code><code>var</code> <code>temp = $(</code><code>'#email'</code><code>).val();</code>

<code>            </code><code>$.ajax({</code>

<code>                </code><code>url:</code><code>'/ops01/login/'</code><code>,</code>

<code>                </code><code>type:</code><code>'POST'</code><code>,</code>

<code>                </code><code>/* 将從元素中擷取到的資料傳到後端,這裡的s=0是用于後端代碼判斷前端的需求是要執行檢測使用者名還是要登陸 */</code>

<code>                </code><code>data:{u:temp,s:0},</code>

<code>                </code><code>success:</code><code>function</code><code>(arg){</code>

<code>        </code><code>/* 将後端傳過來的字典轉換成javascript能識别的字典 */</code>

<code>                    </code><code>var</code> <code>obj = jQuery.parseJSON(arg)</code>

<code>           </code><code>/* 通過後端傳回的狀态碼判斷結果,然後通過Jquery更改樣式的方式控制是否顯示之前定義好的提示資訊 */</code>         

<code>                    </code><code>if</code><code>(obj.statuscode == 1){</code>

<code>                 </code><code>/*  */</code>   

<code>                        </code><code>$(</code><code>'#chk_pCn7em'</code><code>).attr({style:</code><code>"display: inline"</code><code>})</code>

<code>                        </code><code>console.log(obj.statuscode)</code>

<code>                    </code><code>}</code><code>else</code><code>{</code>

<code>                        </code><code>$(</code><code>'#chk_pCn7em'</code><code>).attr({style:</code><code>"display: none"</code><code>})</code>

<code>                    </code><code>}</code>

<code>                </code><code>},</code>

<code>                </code><code>error:</code><code>function</code><code>(){</code>

<code>                    </code><code>console.log(</code><code>'failed'</code><code>)</code>

<code>                </code><code>}</code>

<code>            </code><code>});</code>

<code>        </code><code>})</code>

<code>            </code><code>$(</code><code>'#denglu'</code><code>).click(</code><code>function</code><code>(){</code>

<code>            </code><code>var</code> <code>u = $(</code><code>'#email'</code><code>).val();</code>

<code>            </code><code>var</code> <code>p = $(</code><code>'#password'</code><code>).val();</code>

<code>                </code><code>data:{u:u,p:p,s:1},</code>

<code>                    </code><code>if</code> <code>(obj.statuscode == 0){</code>

<code>                    </code><code>/* 頁面跳轉 */</code>

<code>                        </code><code>window.location.href=</code><code>'http://localhost/ops01/adminindex/'</code>

<code>                        </code><code>$(</code><code>'#promptid'</code><code>).attr({style:</code><code>"display: inline"</code><code>})</code>

<code>            </code><code>})</code>

<code>})</code>

<code>/* 提示: 還可以通過設定屬性的方式修改樣式 例如: $('#stipid').attr('class','stip')  */</code>  

<code>/* 修改選中元素的文本内容 $('#stipid').text('建立成功!')  */</code>

Ajax的好處是整個請求過程是異步的,在不重新整理頁面的情況下完成向後端伺服器的請求。

通過後端代碼、模版語言、&lt;select&gt;标簽實作靈活的下拉清單

<code># Python後端代碼</code>

<code>#擷取groups表中的所有資料</code>

<code>gd </code><code>=</code> <code>groups.objects.</code><code>all</code><code>()</code>

<code>return</code> <code>render_to_response(</code><code>'user-add.html'</code><code>,{</code><code>'form'</code><code>:cuser,</code><code>'gop'</code><code>:gd})</code>

<code>&lt;!-- Html前端代碼 --&gt;</code>

<code>&lt;</code><code>p</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>select</code> <code>name</code><code>=</code><code>"group_id"</code> <code>class</code><code>=</code><code>"gse"</code><code>&gt;</code>

<code>    </code><code>{% for i in gop %}</code>

<code>        </code><code>&lt;</code><code>option</code> <code>value</code><code>=</code><code>"{{ i.gid }}"</code><code>&gt;{{ i.gname }}&lt;/</code><code>option</code><code>&gt;</code>

<code>    </code><code>{% endfor %}</code>

<code>    </code><code>&lt;/</code><code>select</code><code>&gt;</code>

<code>&lt;/</code><code>p</code><code>&gt;</code>

<code>&lt;!-- 編寫思路 --&gt;</code>

<code>&lt;!-- 後端會傳回一個{ 'gop':gd } 的字典,gd是一個清單裡面儲存的是groups表取出來的資料對象,每行資料對應一個對象; gd放入了字典裡,并設定key為'gop'通過傳回字典給前端,前端将可以通過key('gop')得到gd清單,然後通過模版語言循環清單則得到了裡面的每行資料的對象。 --&gt;</code>

<code>&lt;!-- &lt;select&gt;标簽的name屬性是定義傳回給後端程式接收的變量名,而&lt;option&gt;标簽中的value則是對應的值。--&gt;</code>

本文轉自qw87112 51CTO部落格,原文連結:http://blog.51cto.com/tchuairen/1759548