天天看点

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