一、今日内容

一、Django ORM连表操作

Q,F

二、Form表单验证

面向对象

正则

三、Session框架

面向对象

cookie

toanado扩展

二、Django ORM一对多数据创建和查找

1、数据创建

对于不是外键关联的表,可以直接创建

对于通过外键关联的表,可以通过两种方式创建数据:

方式a:通过id添加数据

def user_info(request):
dic = {'username':'xx','age':,'user_type_id':} #通过id添加数据
models.UserInfo.objects.create(**dic)
result = models.UserInfo.objects.all()
for item in result:
print item.username,item.age,item.user_type.caption #对象访问属性

方式b:

    dic = {'username':'alex','age':,'user_type':models.UserType.objects.get(id=)}
models.UserInfo.objects.create(**dic)
result = models.UserInfo.objects.all()
for item in result:
print item.username,item.age,item.user_type.caption #对象访问属性

2、数据正向查找

对于不是外键关联的数据,直接通过如下方式查找

models.UserInfo.objects.filter(username='alex') #不是外键关联的数据

对于外键关联的数据,通过"__"双下划线如下的方式查找:

    result = models.UserInfo.objects.filter(user_type__caption="CEO")    #通过外键关联的数据的查找方式
for item in result:
print item.username,item.age,item.user_type.caption
return HttpResponse("OK")

3、数据反向查找

首先看一下表结构

from django.db import models
class UserType(models.Model):
caption = models.CharField(max_length=) class UserInfo(models.Model):
user_type = models.ForeignKey(UserType)
#在创建数据的时候,需要下来创建选择用户类型,这种情况下需要是一对多
username = models.CharField(max_length=)
age = models.IntegerField()

可以看到UserType是通过外键被UserInfo表关联的表,所以,通过Usertype查找UserInfo表中的数据,称为反向查找

现在有如下需求:要求获取某个人的用户类型,并计算出该用户类型的用户的数量

分析:用户类型存在于UserType表中,但是用户名存在于UserInfo表中,可以直接通过正向查找,在Usertype表中获取指定用户的用户类型,因为用户名是跨表的,需要通过双下划线表示

        通过在UserType表中创建用户类型的对象,利用_set反向关联UserInfo表,查找到对应用户的数量;

    user_type_obj =models.UserType.objects.get(userinfo__username='alex')    #对象(UserType)
print user_type_obj.caption #实例
print user_type_obj.userinfo_set.all().count()
return HttpResponse("OK")

在举一个栗子:

在前面的BBS项目中,如果要获取所有文章的点赞的个数,该如何实现呢?首先请看下面的表结构:

class MyUser(models.Model):
username = models.CharField(max_length=)
password = models.CharField(max_length=)
def __unicode__(self):
return self.username class NEWs(models.Model):
title = models.CharField(max_length=)
content = models.CharField(max_length=)
def __unicode__(self):
return self.title class Favor(models.Model):
user_obj = models.ForeignKey(MyUser)
new_obj = models.ForeignKey(NEWs)
def __unicode__(self):
return "%s --> %s" %(self.user_obj.username,self.new_obj.title)

从上面的表结构可以看出,点赞的表Favor通过外键关联NEWs表和MyUser表,通过NEWs表,获取Favor表中的数据的个数,需要通过反向查找获取,如下:

    new_list = models.NEWs.objects.all()    #获取文章的实例
for item in new_list:
print item.title
print "#############"
print item.content
print item.favor_set.all().count() #反向查找

接下来需求改变,要求查找dali赞过的文章的个数;

分析:如果从NEWs表中开始查找,创建对象的时候需要通过双下划线跨表查询NEWs-->Favor-->MyUser,直到找到条件username=dali为止;

    new_list = models.NEWs.objects.filter(favor__user_obj__username='dali')  #filter返回的是列表,没有返回为[]
for item in new_list:
print item.title
print "#############"
print item.content
print item.favor_set.all().count()

注意:在创建对象的时候,如果是条件查询,需要使用到filter和get,注意区别是:get返回的是字典,无需循环,通过.直接获取需要的字段,并且如果返回值的不唯一或为空,就会报错;而对于filter返回的则是列表,返回值不唯一不会报错,并且如果值为空,返回[],注意获取字段的时候,需要循环; all()返回的也是列表;

4、好了,现在将数据查找的两种方式总结如下:

正向查找: filter(跨表)   对象__跨表的字段

line.对象.跨表的字段

反向查找:filter(跨表)    自动创建一个与表名相同的对象__跨表的字段

line.自动创建一个与表名相同的对象__set.filter()/all()[0:1]

二、Django ORM多对多数据创建和查找

1、正向添加数据

首先看一下表结构,对于多对多来讲,外键关联的字段HostAdmin/host可以放在任何一张表中,只不过这时候需要注意正向和反向即可

class Host(models.Model):
hostname = models.CharField(max_length=)
port = models.IntegerField() class HostAdmin(models.Model):
username = models.CharField(max_length=)
email = models.CharField(max_length=)
host=models.ManyToManyField(Host)

接下来创建数据

  models.Host.objects.create(hostname='c1',port=)
models.Host.objects.create(hostname='c2',port=)
models.Host.objects.create(hostname='c3',port=)
models.HostAdmin.objects.create(username='alex',email='1@live.com')
models.HostAdmin.objects.create(username='root',email='2@live.com')
models.HostAdmin.objects.create(username='dali',email='3@live.com')
models.HostAdmin.objects.create(username='haojie',email='4@live.com')

数据内容如下所示:

现在需要在关联的表host表中创建数据如下:

正向创建数据

    admin_obj=models.HostAdmin.objects.get(username='dali')    #创建username的对象
host_list=models.Host.objects.filter(id__lt=) #创建主机id小于3的对象
admin_obj.host.add(*host_list) #添加数据
return HttpResponse("OK")

2、反向数据添加

    host_obj =models.Host.objects.get(id=)
admin_list = models.HostAdmin.objects.filter(id__gt=) #id值大于1
host_obj.hostadmin_set.add(*admin_list) #反向数据添加

总结:正向数据添加还是反向数据添加,取决于多对多的关联的字段存在于哪个表中;相同点是:都是一张表中的一个固定的值对另外一张表的多个值;

3、Django 多对多自定义第三张关系表

如下三张表,对于第三张关系表,第一张表和第二张表是第三张表的外键,其表中的字段全部通过外键关联其他的表,那么可不可以让第三张表中存在其他的字段呢?答案是可以的

看下面:Django 多对多ORM创建第三张自定义的关系表,通过through参数实现;

class Host1(models.Model):
hostname = models.CharField(max_length=)
port = models.IntegerField() class HostAdmin1(models.Model):
username = models.CharField(max_length=)
email = models.CharField(max_length=)
host=models.ManyToManyField(Host1,through='HostRelation') class HostRelation(models.Model):
c1=models.ForeignKey(Host1)
C2=models.ForeignKey(HostAdmin1)
#可以在下面继续增加其他的字段,如果需要的话

那问题来了?自定义的第三张表有了,数据如何写入呢?

事实上,此时在第三张表中写入数据,是写入的id的值,有两种方式:通过查询对象写入和直接写入,看下面

#通过查询对象写入,需要查询之后执行数据库操作    
models.HostRelation.objects.create(
c1=models.Host1.objects.get(id=),
C2=models.HostAdmin1.objects.get(id=)
)
#直接写入,无需查询,推荐的方式;    
models.HostRelation.objects.create( #0次数据库查询,一次数据库插入
c1_id=,
C2_id=,
)

4、Django ORM多对多数据查询的两种方式

方式1:

    #正向查
admin_obj =models.HostAdmin.objects.get(id=)
admin_obj.host.all() #反向查
host_obj =models.Host.objects.get(id=)
host_obj.hostadmin_set.all()

方式2:通过自定义的第三张表查询(推荐)

    relation_list = models.HostRelation.objects.all()
for item in relation_list:
print item.c1.hostname
print item.C2.username relation_list1 = models.HostRelation.objects.filter(C2__username='alex')
for item in relation_list1:
print item.c1.hostname
print item.C2.username

比较:第二种方式可以查询所有的数据,并且操作数据库的次数少,,并且便于扩展(添加新的字段)推荐使用;

5、ORM查询使用select_related()

ret = models.UserInfo.objects.all()
print ret.query SQL为:
SELECT "app01_userinfo"."id", 
  "app01_userinfo"."user_type_id",
  "app01_userinfo"."username",
  "app01_userinfo"."age"
FROM "app01_userinfo"

ret = models.UserInfo.objects.all().select_related() 
print ret.query SQL为:
SELECT
"app01_userinfo"."id",
"app01_userinfo"."user_type_id",
"app01_userinfo"."username",
"app01_userinfo"."age",
"app01_usertype"."id",
"app01_usertype"."caption"
FROM "app01_userinfo" INNER JOIN "app01_usertype" ON ( "app01_userinfo"."user_type_id" = "app01_usertype"."id" )

select_related()会将外键关联的表进行关联查询,会将全部Foreignkey加载到内存;

6、ORM之F和ORM之Q

需求:将数据库中age字段的值都加以 model.tb.object.all().update(age=F('age')+1)    #F表示当前行的数据

一般对于使用ORM filter查询数据的时候,只能添加一个条件,那么如果需要添加多个条件呢?

ORM Q可以创建多个条件供filter查询

现在要求查询:主机名为c1或c2或c3或c4并且状态都为在线的主机
from django.db.models import Q
con=Q()
主机名:c1,c2,c3,c4 ===> q1 =Q()
q1=Q()
q1.connector="OR"
q1.children.append(('hostname',"c1")) #此处的主机名可以使用双下划线进行跨表关联
q1.children.append(('hostname',"c2"))
q1.children.append(('hostname',"c3"))
q1.children.append(('hostname',"c4")) 状态:上线,上架 ===>q2 ==Q()
q2=Q()
q2.connector="OR"
q2.children.append(('status',"online"))
q2.children.append(('status',"online2")) con.add((q1,'ADD'))
con.add((q2,'ADD'))
models.TB1.objects.filter(con)

就是将q1和q2两个条件一起放到con条件下面,产生多个条件;

#!/usr/bin/env python
# -*- coding:utf- -*- import json from backend.response.base_response import BaseResponse
from django.db import transaction
from web_manage.dal import asset
from web_manage.dal import user_profile
from web_manage.dal import contract
from web_manage.dal import idc
from web_manage.dal import server
from web_manage.dal import device_status
from web_manage.dal import business_unit
from web_manage.dal import device_type
from web_manage.dal import nic
from web_manage.dal import memory
from web_manage.dal import disk
from web_manage.dal import handle_log
from django.db.models import Q def asset_import_single(**kwargs):
response = BaseResponse()
try:
with transaction.atomic():
manage_ip = kwargs.pop('manage_ip')
hostname = kwargs.pop('hostname')
sn = kwargs.pop('sn') kwargs['idc'] = idc.get_obj_by_id(kwargs['idc'])
kwargs['contract'] = contract.get_obj_by_id(kwargs['contract'])
#kwargs['manage_user'] = user_profile.get_obj_by_id(kwargs['manage_user'])
kwargs['device_status'] = device_status.get_obj_by_code('')
kwargs['device_type'] = device_type.get_obj_by_code('') kwargs['business_unit'] = business_unit.get_obj_by_id(kwargs['business_unit']) asset_obj = asset.add(**kwargs)
server.add(asset=asset_obj, manage_ip=manage_ip, hostname=hostname, sn=sn) response.data = asset_obj
response.status = True
except Exception, e:
response.message = e
return response def get_asset_lists_count(conditions):
response = BaseResponse()
try:
# base ip get server object ip
ips = conditions.get('ips__contains', None)
if not ips:
pass
else:
del conditions['ips__contains'] q_ip = Q()
q_ip.connector = 'OR'
server_ids = []
for item in (ips if ips else []):
q_ip.children.append(("ipaddrs__contains", item))
server_ips = nic.get_field_by_q_group(q_ip, 'server_info', *['server_info__id'])
for item in server_ips:
if item:
server_ids.append(item.values()[])
if server_ids:
conditions['server__id'] = server_ids
else:
conditions['server__id'] = [, ] # create search condition
con = Q()
for k, v in conditions.items():
temp = Q()
temp.connector = 'OR'
for item in v:
temp.children.append((k, item))
con.add(temp, 'AND') # do search
result = asset.get_asset_lists_q_count(con) response.data = result
response.status = True except Exception,e:
response.message = str(e)
return response def get_asset_lists(conditions, start, end):
response = BaseResponse()
try:
values = ['id', 'cabinet_num', 'cabinet_order', 'server__manage_ip', 'server', 'server__hostname', 'server__sn',
'device_type__id', 'device_type__name',
'device_status__id', 'device_status__name',
'business_unit__id', 'business_unit__name',
'idc__id', 'idc__display',
'contract__id', 'contract__name']
# base ip get server object ip
ips = conditions.get('ips__contains', None)
if not ips:
pass
else:
del conditions['ips__contains'] q_ip = Q()
q_ip.connector = 'OR'
server_ids = []
for item in (ips if ips else []):
q_ip.children.append(("ipaddrs__contains", item))
server_ips = nic.get_field_by_q_group(q_ip, 'server_info', *['server_info__id'])
for item in server_ips:
if item:
server_ids.append(item.values()[])
if server_ids:
conditions['server__id'] = server_ids
else:
conditions['server__id'] = [, ] # create search condition
con = Q()
for k, v in conditions.items():
temp = Q()
temp.connector = 'OR'
for item in v:
temp.children.append((k, item))
con.add(temp, 'AND') # do search
result = asset.get_asset_lists_q(start, end, con, *values) # get ip info
for item in result:
ips = nic.get_field_by_server(item['server'], *['ipaddrs', ])
item['ips'] = list(ips) result = list(result) response.data = result
response.status = True except Exception,e:
response.message = str(e)
return response def __asset_update_log(row, user):
with transaction.atomic():
asset_obj = asset.get_asset_by_id(row['id'])
server_obj = server.get_obj_by_asset(asset_obj)
log_list = [] if(row.has_key('cabinet_order')):
log_list.append(u"机柜由【%s】变更为【%s】" % (asset_obj.cabinet_order, row['cabinet_order']))
asset_obj.cabinet_order = row['cabinet_order'] if(row.has_key('cabinet_num')):
log_list.append(u"柜上位置由【%s】变更为【%s】" % (asset_obj.cabinet_num, row['cabinet_num']))
asset_obj.cabinet_num = row['cabinet_num'] if(row.has_key('contract')):
log_list.append(u"合同由【%s】变更为【%s】" % (asset_obj.contract.name, row['contract']))
asset_obj.contract = contract.get_obj_by_name(row['contract']) if(row.has_key('business_unit')):
log_list.append(u"业务线由【%s】变更为【%s】" % (asset_obj.business_unit.name, row['business_unit']))
asset_obj.business_unit = business_unit.get_obj_by_name(row['business_unit']) if(row.has_key('idc')):
log_list.append(u"IDC由【%s】变更为【%s】" % (asset_obj.idc.display, row['idc']))
asset_obj.idc = idc.get_obj_by_display(row['idc']) if(row.has_key('device_status')):
log_list.append(u"设备状态由【%s】变更为【%s】" % (asset_obj.device_status.name, row['device_status']))
asset_obj.device_status = device_status.get_obj_by_name(row['device_status']) if(row.has_key('manage_ip')):
log_list.append(u"管理IP由【%s】变更为【%s】" %(server_obj.manage_ip, row['manage_ip']))
server_obj.manage_ip = row['manage_ip'] if(row.has_key('hostname')): log_list.append(u"主机名由【%s】变更为【%s】" %(server_obj.hostname, row['hostname']))
server_obj.hostname = row['hostname'] if(row.has_key('sn')):
log_list.append(u"SN号由【%s】变更为【%s】" %(server_obj.sn, row['sn']))
server_obj.sn = row['sn'] server_obj.save()
asset_obj.save()
if log_list:
handle_log.write_handle_log(asset_obj, user, ';'.join(log_list)) def del_asset(rows):
response = BaseResponse()
error_count =
error_message = []
try:
rows = json.loads(rows)
except Exception, e:
response.status =
response.data = str(e)
response.message = error_message
return response for row in rows:
try:
with transaction.atomic():
asset_obj = asset.get_asset_by_id(row['nid'])
server_obj = asset_obj.server
nic.del_by_server(server_obj)
disk.del_by_server(server_obj)
memory.del_by_server(server_obj)
handle_log.del_by_asset(asset_obj)
server_obj.delete()
asset_obj.delete()
except Exception, e:
error_count +=
error_message.append({'num': row['num'], 'message': str(e)}) if error_count == :
response.status =
response.data = "删除%d条,成功%d." % (len(rows), len(rows)-error_count)
elif error_count > :
response.status =
response.data = "删除%d条,成功%d,失败%d." % (len(rows), len(rows)-error_count, error_count)
response.message = error_message
return response def modify_multi_asset(data, user):
# 临时
response = BaseResponse()
rows = json.loads(data)
error_count =
error_message = []
user = json.loads(user)
current_user_id = user['id']
current_user_obj = user_profile.get_obj_by_id(current_user_id)
for item in rows:
try:
__asset_update_log(item, current_user_obj)
except Exception, e:
error_count +=
error_message.append({'num': item['num'], 'message': str(e)})
if error_count == :
response.status =
response.data = "更新%d条,成功%d." % (len(rows), len(rows)-error_count)
elif error_count > :
response.status =
response.data = "更新%d条,成功%d,失败%d." % (len(rows), len(rows)-error_count, error_count)
response.message = error_message
print response
return response def get_asset_detail(nid):
response = BaseResponse()
try:
asset_obj = asset.get_asset_by_id(nid)
nic_list = nic.get_objs_by_server(asset_obj.server)
mem_list = memory.get_objs_by_server(asset_obj.server)
disk_list = disk.get_objs_by_server(asset_obj.server)
log_list = handle_log.get_handle_log(asset_obj=asset_obj)
result = {'asset': asset_obj, 'nic': nic_list, 'memory': mem_list, 'disk': disk_list, 'log': log_list}
response.status = True
response.data = result
except Exception, e:
response.message = str(e)
return response def init_config(nid):
response = BaseResponse()
try:
asset_obj = asset.get_asset_by_id(nid)
result = asset.get_init(asset_obj.server.manage_ip)
asset_obj.server.service_sn = result['service_sn']
asset_obj.server.sn = result['sn']
asset_obj.server.first_mac = result['first_mac']
asset_obj.server.save()
response.status = True
response.data = '初始化成功.'
except Exception, e:
response.status = False
response.message = str(e) return response # ########################## 获取字典表 ########################## # def get_all_idc():
response = BaseResponse()
try:
values = ['id','display']
result = idc.get_all(*values)
result = list(result)
response.data = result
response.status = True
except Exception,e:
response.message = str(e)
return response def get_all_status():
response = BaseResponse()
try:
values = ['id', 'name', ]
result = device_status.get_all(*values)
result = list(result)
response.data = result
response.status = True
except Exception,e:
response.message = str(e)
return response def get_all_user_basic_op():
response = BaseResponse()
try:
values = ['id', 'name', ]
result = user_profile.get_all_basic_op(*values)
result = list(result)
response.data = result
response.status = True
except Exception,e:
response.message = str(e)
return response def get_all_business_unit():
response = BaseResponse()
try:
values = ['id', 'name', ]
result = business_unit.get_all(*values)
result = list(result)
response.data = result
response.status = True
except Exception,e:
response.message = str(e)
return response def get_all_contract():
response = BaseResponse()
try:
values = ['id', 'name', ]
result = contract.get_all(*values)
result = list(result)
response.data = result
response.status = True
except Exception,e:
response.message = str(e)
return response

7、作业:搜索功能开发

那么作业来了:
前端输入多个用户、多个年龄或者用户类型来搜索用户 姓名:<input name="username" />
年龄:<input name="age" />
用户类型:<input name="user_type__caption" /> #跨表 AJAX
{
"username":[c1,c2,c3],
"age":[,]
} 后台
dic 在前端获取
con = Q()
for key,value in dic:
q=Q()
q.connettor="OR"
for v in value:
q.children.append((key,v))
con.add(q,'ADD') model.Tb1.objects.filter(con)

Django Web补充的更多相关文章

  1. Django web 开发指南 no such table:

    在学习django web开发指南时,发布新博客点击save后会有error提示:no such table balabalabala... 百度了一下说重新运行manage.py syncdb 就可 ...

  2. django web 中添加超链接

    django web 中添加不传参的超链接的方法如下: html: 在web中的超链接中加入一下url <a href="{% url 'app_name.views.url_func ...

  3. Python Django(WEB电商项目构建)

    (坚持每一天,就是成功) Python Django Web框架,Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型M,模板T和视图V组成. 安装Pyth ...

  4. 教程:Visual Studio 中的 Django Web 框架入门

    教程:Visual Studio 中的 Django Web 框架入门 Django 是高级 Python 框架,用于快速.安全及可扩展的 Web 开发. 本教程将在 Visual Studio 提供 ...

  5. Django Web开发学习笔记(1)

    一.Python的标准类型 (1)bool型 >>> bool("") False >>> bool(None) False >>& ...

  6. Django组件补充(缓存,信号,序列化)

    Django组件补充(缓存,信号,序列化) Django的缓存机制 1.1 缓存介绍 1.缓存的简介 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑 ...

  7. Python学习---django知识补充之CBV

    Django知识补充之CBV Django: url    -->  def函数      FBV[function based view]  用函数和URL进行匹配 url    --> ...

  8. Django 知识点补充

    Django 知识点补充 1 Django如何在Model保存前做一定的固定操作,比如写一条日志 (1)利用Django的Model的Signal Dispatcher, 通过django.db.mo ...

  9. [oldboy-django][1初始django]web框架本质 + django框架 + ajax

    web框架本质 浏览器(socket客户端) - 发送请求(ip和端口,url http://www.baidu.com:80/index/) - GET 请求头(数据请求行的url上: Http1. ...

随机推荐

  1. jsp添加背景音乐

    在<head></head>间假如标签<embed src="文件地址" loop="11" autostar="tru ...

  2. rails: 的cookie小结

    cookie会随着浏览器每次发起的请求(request)传给服务器进行读取,而服务器则会在应答(response)中携带cookie写在本机上.因此,cookie是存储在本地的.而且由于cookie的 ...

  3. Intellij IDEA +MAVEN+Jetty实现Spring整合Mybatis

    1 pom.xml(这里出现transaction错误,是版本的问题) <project xmlns="http://maven.apache.org/POM/4.0.0" ...

  4. POJ2778 DNA sequence

    题目大意:给出m个疾病基因片段(m<=10),每个片段不超过10个字符.求长度为n的不包含任何一个疾病基因片段的DNA序列共有多少种?(n<=2000000000) 分析:本题需要对m个疾 ...

  5. 单点登录SSO

    转载自 http://www.blogjava.net/xcp/archive/2010/04/13/318125.html   摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当 ...

  6. JQGrid 学习1

    这几天一直在学习基于MVC的JQGrid. 记得刚毕业时候做web最头疼的就是GridView,各种分页查询删除,后来学习了Ajax,使用的jqury UI框架ligerui给公司做ERP系统,再后来 ...

  7. Android学习笔记(十二)

    Fragment是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间. 碎片的简单用法:新建一个FragmentTest项目,然后新建一个左侧碎片布局left_fragmen ...

  8. JVM实用参数(八)GC日志

    本系列的最后一部分是有关垃圾收集(GC)日志的JVM参数.GC日志是一个很重要的工具,它准确记录了每一次的GC的执行时间和执行结果,通过分析GC日志可以优化堆设置和GC设置,或者改进应用程序的对象分配 ...

  9. php中urldecode()和urlencode()

    urlencode()函数原理就是首先把中文字符转换为十六进制,然后在每个字符前面加一个标识符%.urldecode()函数与urlencode()函数原理相反,用于解码已编码的 URL 字符串,其原 ...

  10. 使用Jenkins可持续集成maven项目

    首先下载最新的Jenkins的war包,放在tomcat的webapps的目录下,然后运行,例如: http://121.42.62.45:8080/jenkins/ 然后按照一步步的提示,下载相关的 ...