码迷,mamicode.com
首页 > Web开发 > 详细

Django Web补充

时间:2016-08-08 00:52:38      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:

一、今日内容

一、Django ORM连表操作

Q,F

 

二、Form表单验证

  面向对象

   正则

 

三、Session框架

    面向对象

    cookie

    toanado扩展

 

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

1、数据创建

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

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

  方式a:通过id添加数据

def user_info(request):
    dic = {username:xx,age:88,user_type_id:1}   #通过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:73,user_type:models.UserType.objects.get(id=1)}
    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=32)

class UserInfo(models.Model):
    user_type = models.ForeignKey(UserType)
    #在创建数据的时候,需要下来创建选择用户类型,这种情况下需要是一对多
    username = models.CharField(max_length=32)
    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=32)
    password = models.CharField(max_length=64)
    def __unicode__(self):
        return self.username

class NEWs(models.Model):
    title = models.CharField(max_length=32)
    content = models.CharField(max_length=32)
    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=32)
    port = models.IntegerField()

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

接下来创建数据

  models.Host.objects.create(hostname=c1,port=80)
  models.Host.objects.create(hostname=c2,port=80)
  models.Host.objects.create(hostname=c3,port=80)
  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=3)     #创建主机id小于3的对象
    admin_obj.host.add(*host_list)                      #添加数据
    return HttpResponse("OK")

 2、反向数据添加

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

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

 

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

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

技术分享技术分享技术分享

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

 

class Host1(models.Model):
    hostname = models.CharField(max_length=32)
    port = models.IntegerField()

class HostAdmin1(models.Model):
    username = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    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=1), C2=models.HostAdmin1.objects.get(id=2) )
#直接写入,无需查询,推荐的方式;    
models.HostRelation.objects.create( #0次数据库查询,一次数据库插入 c1_id
=2, C2_id=1, )

技术分享

 

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

方式1:

    #正向查
    admin_obj =models.HostAdmin.objects.get(id=1)
    admin_obj.host.all()

    #反向查
    host_obj =models.Host.objects.get(id=1)
    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

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

 

Django Web补充

标签:

原文地址:http://www.cnblogs.com/cqq-20151202/p/5744824.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!