一、Model连表操作
一对一和一对多
表结构如下:
1
2
3
4
5
6
7
8
9
10
|
class user_type(models.Model):
name = models.CharField(max_length = 50 )
class user(models.Model):
username = models.CharField(max_length = 50 )
password = models.CharField(max_length = 50 )
email = models.EmailField()
usertype = models.ForeignKey(user_type)
user.objects. filter (usertype__id = 1 ).values( 'username' )
|
示例
1
2
3
4
5
6
7
8
|
# 查询user表中,用户类型为管理员的所有用户 data = user.objects. filter (usertype__name = '管理员' )
# 取单字段(比如只取username字段) data = user.objects. filter (usertype__name = '管理员' ).values( 'username' )
# 大于条件 data = user.objects. filter (usertype__id__gt = 3 )
|
这里通过__(双下划线)表示连表查询,比如usertype__name相当于操作到了user_type表的name字段。
多对多关系
表结构如下:
1
2
3
4
5
6
7
8
9
|
class user(models.Model):
username = models.CharField(max_length = 50 )
password = models.CharField(max_length = 50 )
email = models.EmailField()
usertype = models.ForeignKey(user_type)
class groups(models.Model):
gname = models.CharField(max_length = 255 )
guser = models.ManyToManyField( 'user' )
|
1
2
3
4
5
6
7
8
9
10
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
|
user_obj = models.user.objects.get(name = u 'tuchao' )
user_objs = models.user.objects. all ()
group_obj = models.groups.objects.get(gname = 'dev' )
group_objs = models.groups.objects. all ()
# 添加数据 #group_obj.guser.add(user_obj) #group_obj.guser.add.add(*user_objs) # 删除数据 #group_obj.guser.remove(user_obj) #group_obj.guser.remove(*user_objs) # 这里有点绕,用户表的对象.组表的名称(与用户相关系的表其中有定义与用户表的多对多关系)_set.add(组表的对象) # 添加数据 #user_obj.groups_set.add(group_obj) #user_obj.groups_set.add(*group_objs) # 删除数据 #user_obj.groups_set.remove(group_obj) #user_obj.groups_set.remove(*group_objs) # 获取数据 #print group_obj.guser.all() #print group_obj.guser.all().filter(id=1) # 获取数据 #print user_obj.groups_set.all() #print user_obj.groups_set.all().filter(gname='tuchao') #print user_obj.groups_set.all().filter(gname='tyz') # 使用MySQL事务的方式完成多对多关系的数据插入,当使用事务方式的时候,在同一个事务中的语句要么全部执行成功,要么一个都不会执行,保证了数据的完整性。 #导入相关库 from django.db import connection,transaction
try :
''' 启动事务 '''
with transaction.atomic():
''' 先给用户信息表插入数据 '''
user.objects.create(username = username,password = password,realname = realname,email = email,ugid = group_id)
''' 然后通过用户名获取该条记录的数据,取出对应关系的ID值插入到关系表 ''' d1 = user.objects.get(username = username)
uuid = d1.uid
ugid = d1.ugid
userandgroup.objects.create(gid = ugid,uid = uuid)
except Exception,err:
print (err)
|
二、Form 创建自定义错误信息
forms.py的文件
1
2
3
4
5
6
7
8
9
10
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
|
class RegisterForm(forms.Form):
username = forms.CharField(widget = forms.TextInput(attrs = { 'class' : 'user_name' , 'placeholder' : '用户名' }),help_text = '100 characters max.' )
password = forms.CharField(widget = forms.PasswordInput(attrs = { 'class' : 'pwd' , 'placeholder' : '密码' }))
real_name = forms.CharField(widget = forms.TextInput(attrs = { 'placeholder' : '真实姓名' }))
email = forms.CharField(widget = forms.EmailInput(attrs = { 'placeholder' : 'Email' }))
gender = forms.BooleanField()
# 这里的'placeholder':'用户名' 是input里面的参数。 如: <input name="hostname" placeholder="hostname" /> class AdminHostAdd(forms.Form):
othername = forms.CharField(widget = forms.TextInput(attrs = { 'class' : 'othername' }),error_messages = { 'required' :( '业务名不能为空' ), 'invalid' : '业务名格式错误' })
hostname = forms.CharField(widget = forms.TextInput(attrs = { 'class' : 'hostname' }),error_messages = { 'required' :( '主机名不能为空' ), 'invalid' : '主机名格式错误' })
hardconfig = forms.CharField(widget = forms.TextInput(attrs = { 'class' : 'hardconfig' }),error_messages = { 'required' :( '硬件配置信息不能为空' )})
wip = forms.IPAddressField(error_messages = { 'required' :( '外网IP不能为空' ), 'invalid' : 'IP格式错误' })
lip = forms.IPAddressField(error_messages = { 'required' :( '内网IP不能为空' ), 'invalid' : 'IP格式错误' })
# error_messages:required对应的是当提交内容为空所提示的信息,invalid则表示提交的数据格式错误所提示的信息。 # 在页面中输出自定义错误信息 # 在功能函数中截取的部分代码,获取自定义错误信息 ret = { 'data' : None , 'error' : 'None' }
ret[ 'data' ] = form
firstmessage = form.errors.as_data()
# 将获取的错误信息传给字典,key为error ret[ 'error' ] = firstmessage.values()[ 0 ][ 0 ].messages[ 0 ]
# 在输出信息的时候返回页面和字典 return render_to_response( 'admin-host-add.html' ,ret)
# 在Html中获取返回的字典数据 <span class = "hostaddstatus" >{{ error }}< / span>
|
三、学习使用Ajax
Ajax的基本语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/* 首先引入Jquery */ <script src= "/static/assets/js/jquery-1.12.0.js" ></script>
<script type= "text/javascript" >
function DoAjax(){
/* 获取选定元素的数据 */
var temp = $( '#text01' ).val();
$.ajax({
/* 提交请求的url */ url: '/ops01/ad/' ,
/* 提交请求的方式 */ type: 'POST' ,
/* 返回的数据,key:value */ data:{data:temp},
/* 请求成功所执行的方法 */
success: function (arg){
console.log( 'success' );
},
/* 请求失败所执行的方法 */
error: function (){
console.log( 'failed' )
}
});
} </script> |
功能实战
实现登陆页面在没有登陆的情况下检测用户名是否存在,然后通过Ajax实现密码错误检测和登陆跳转。
1
2
3
4
5
6
7
8
9
10
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
|
# Python 后端功能代码实现 #!/usr/local/python27/bin/python2.7 # coding=utf8 # noinspection PyUnresolvedReferences from django.shortcuts import render
from ops01.forms import RegisterForm,AdminHostAdd,CreateGroups
from django.http import HttpResponse
from django.shortcuts import render_to_response
from ops01.models import *
from django.db import connection,transaction
import json
def Login(request):
if request.method = = 'POST' :
username = request.POST.get( 'u' , None )
password = request.POST.get( 'p' , None )
code = request.POST.get( 's' , None )
print (username,password,code)
data = { 'statuscode' : 0 , 'status' : 'ok' }
''' 当code=0 时表示检查用户名是否存在,当code=1 时表示尝试登陆''' if code = = '0' :
un = user.objects. filter (username = username)
if un:
return HttpResponse(json.dumps(data))
else :
data[ 'statuscode' ] = 1
data[ 'status' ] = 'failed'
return HttpResponse(json.dumps(data))
else :
un = user.objects. filter (username = username)
data = un.values()[ 0 ]
print data.get( 'password' )
if data.get( 'password' ) = = password:
data = { 'statuscode' : 0 , 'status' : 'ok' }
return HttpResponse(json.dumps(data))
else :
data[ 'statuscode' ] = 1
data[ 'status' ] = 'failed'
''' 返回一个json格式的字典数据 '''
return HttpResponse(json.dumps(data))
return render_to_response( 'login.html' ,{})
|
1
2
3
4
5
6
7
8
9
10
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
/* 前端javascript代码实现 */ <script src= "/static/assets/js/jquery-1.12.0.js" ></script>
<script type= "text/javascript" >
$( function (){
$( '#email' ).blur( function (){
var temp = $( '#email' ).val();
$.ajax({
url: '/ops01/login/' ,
type: 'POST' ,
/* 将从元素中获取到的数据传到后端,这里的s=0是用于后端代码判断前端的需求是要执行检测用户名还是要登陆 */
data:{u:temp,s:0},
success: function (arg){
/* 将后端传过来的字典转换成javascript能识别的字典 */
var obj = jQuery.parseJSON(arg)
/* 通过后端返回的状态码判断结果,然后通过Jquery更改样式的方式控制是否显示之前定义好的提示信息 */ if (obj.statuscode == 1){
/* */ $( '#chk_pCn7em' ).attr({style: "display: inline" })
console.log(obj.statuscode)
} else {
$( '#chk_pCn7em' ).attr({style: "display: none" })
}
},
error: function (){
console.log( 'failed' )
}
});
})
$( '#denglu' ).click( function (){
var u = $( '#email' ).val();
var p = $( '#password' ).val();
$.ajax({
url: '/ops01/login/' ,
type: 'POST' ,
data:{u:u,p:p,s:1},
success: function (arg){
var obj = jQuery.parseJSON(arg)
if (obj.statuscode == 0){
/* 页面跳转 */
window.location.href= 'http://localhost/ops01/adminindex/'
} else {
$( '#promptid' ).attr({style: "display: inline" })
}
},
error: function (){
console.log( 'failed' )
}
})
})
}) /* 提示: 还可以通过设置属性的方式修改样式 例如: $('#stipid').attr('class','stip') */ /* 修改选中元素的文本内容 $('#stipid').text('创建成功!') */ </script> |
Ajax的好处是整个请求过程是异步的,在不刷新页面的情况下完成向后端服务器的请求。
通过后端代码、模版语言、<select>标签实现灵活的下拉列表
1
2
3
4
5
|
# Python后端代码 #获取groups表中的所有数据 gd = groups.objects. all ()
return render_to_response( 'user-add.html' ,{ 'form' :cuser, 'gop' :gd})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!-- Html前端代码 --> < p >
< select name = "group_id" class = "gse" >
{% for i in gop %}
< option value = "{{ i.gid }}" >{{ i.gname }}</ option >
{% endfor %}
</ select >
</ p >
<!-- 编写思路 --> <!-- 后端会返回一个{ 'gop':gd } 的字典,gd是一个列表里面保存的是groups表取出来的数据对象,每行数据对应一个对象; gd放入了字典里,并设置key为'gop'通过返回字典给前端,前端将可以通过key('gop')得到gd列表,然后通过模版语言循环列表则得到了里面的每行数据的对象。 --> <!-- <select>标签的name属性是定义返回给后端程序接收的变量名,而<option>标签中的value则是对应的值。--> |
本文转自qw87112 51CTO博客,原文链接:http://blog.51cto.com/tchuairen/1759548