博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django中级篇之Model专题
阅读量:5766 次
发布时间:2019-06-18

本文共 4910 字,大约阅读时间需要 16 分钟。

ORM

就是用面向对象的方式去操作数据库的创建表以及增删改查等操作

到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:

  • 创建数据库,设计表结构和字段
  • 使用 MySQLdb 来连接数据库,并编写数据访问层代码
  • 业务逻辑层去调用数据访问层执行数据库操作
 View Code

django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM)

一、创建表

1、基本结构

注意:

  1、创建表的时候,如果我们不给表加自增列,生成表的时候会默认给我们生成一列为ID的自增列,当然我们也可以自定义

  2、如果我们给某一列设置了外键的时候,生成表的时候,该列的表名会自动生成auter_id(即俩个字段中间用_连接起来)

  3、创建外键的时候 models.ForeignKey(UserType)  ForeignKey中参数代表的类必须在其上面,否则就必须写成字符串的形式

from django.db import modelsclass userinfo(models.Model):    nid = models.AutoField(primary_key=True)    name = models.CharField(max_length=30)    email = models.EmailField()    memo = models.TextField()    class Meta:        verbose_name = '用户名'        verbose_name_plural = verbose_name    def __str__(self):     #相当于tornado中的__repr__        return self.name

 

class Host_To_Group(models.Model):    nid = models.AutoField(primary_key=True)    host_id = models.ForeignKey('Host')    group_id = models.ForeignKey('Group')    class Meta:        index_together = ('host_id','Group') #联合索引        unique_together = [                #联合唯一索引            ('host_id', 'Group')        ]

 

 更多字段1
 更多字段2
 更多参数

通过内部类Meta给数据模型类增加扩展属性:

     class Meta:

             verbose_name='名称'      #表名由英文转换成中文了

             verbose_name_plural='名称复数形式'

             ordering='排序字段' 

2、连表结构(当我们在类中写上这样的字段后,就会为我们自动创建一张关系表)

  • 一对多:models.ForeignKey(其他表)
  • 一对多:就是主外键关系;
  • 多对多:models.ManyToManyField(其他表)
  • 多对多:多个主外键的关系
  • 一对一:models.OneToOneField(其他表)
  • 一对一:实质就是在主外键的关系基础上,给外键加了一个UNIQUE的属性

二、操作表

1、基本操作

-------------------用于获取后台提交的数据----------------------

username=req.POST.get('username')

password=req.POST.get('password')

----------------------------------------------------------------

 基本操作---增删改查

2、进阶操作(了不起的双下划线)

利用双下划线将字段和对应的操作连接起来

 进阶操作

3、连表操作(了不起的双下划线)

对象.query---------------------查看代码的sql语句

利用双下划线和 _set 将表之间的操作连接起来

1>一对多

正向查找

 表结构实例
#不在filter()或values()中查询使用ret = models.UserInfo.objects.all()for i in ret :    print(type(i),i.user,i.user_type.caption)#得到的ret是一个queryset对象,只有我们循环我们得到每一行的一个对象的时候才可以用.字段名获取数据# 想获取和其有联系表的数据的时候,i.user_type得到的是一个有联系表的对象,我们就可以获取数据了
#在filter()或values()中查询使用ret1 = models.UserInfo.objects.filter(user_type__caption='管理员').all().values('user','user_type__caption')ret2 = models.UserInfo.objects.all().values('user','user_type__caption')print(type(ret1),ret1)print(type(ret2),ret2)#我们查的是userinfo表中的user,所以应该user中数据全部显示,而'user_type__caption'即另一张表中的数据根据user对应的值进行显示

 反向查找

1、不在filter()或values()中查询使用

ret = models.UserInfo.objects.all()for i in ret :    print(type(i.user_type),i.user_type)ret1 = models.UserType.objects.all()for j in ret1:    print(type(j.userinfo_set),j.userinfo_set)------------------------------------------------------------------------------------------------------------------------------------------------------
UserType object
UserType object
UserType object
.RelatedManager'> app1.UserInfo.None
.RelatedManager'> app1.UserInfo.None
.RelatedManager'> app1.UserInfo.None------------------------------------------------------------------------------------------------------------------------------------------------------1、以上我们可以看出有外键的类中存在user_type字段,可以通过这个字段就能得到和其对应表的对象,从而获取另一张表中的信息2、而不存在外键的表中其实隐藏了一个userinfo_set字段,我们同样可以通过这个字段获取其对应表中的信息------->对应表表名_set

2、在filter()或values()中查询使用

ret1 = models.UserType.objects.all().values('caption','userinfo')ret2 = models.UserType.objects.all().values('caption','userinfo__user')print(ret1)print(ret2)#如果反向查找的条件放到filter()或values()中的时候就不能用表名_set了,而用 ------>表名__

2>多对多

创建表的三种方式:

第三张表中自动生成联合唯一索引

1、自己创建第三张表(适用于我们在第三张表中自定义列)

 自己创建

2、利用ManyToManyField()

 ManyToMany

3、自己创第三种表+ManyToManyField()-----虽然这样看起来后面的在创建数据库的时候没用,但是其在操作数据库的时候有用

中间模型表如果是通过through制定的,add create方法会失效 

 自己创建+ManyToManyField(through='xxx')
 多对多之增删改查

慎用:h1.group_set.all().delete()------------同时删除关系表和关联表中数据

----------------------------------------------------重点-----------------------------------------------

以上如果我们利用第三种方法建立表的时候,add、set等方法会失效,不能操作,只能查看

and和or

其中F表示可以让某一列的数据在当前的状态下自增多少,而我们平时用的updata只能把某一列数据都改变成同一个值

其中Q表示搜索条件可以有or和and

# F 使用查询条件的值    #    # from django.db.models import F    # models.Tb1.objects.update(num=F('num')+1)    # Q 构建搜索条件    from django.db.models import Q    # con = Q()    #    # q1 = Q()    # q1.connector = 'OR'    # q1.children.append(('id', 1))    # q1.children.append(('id', 10))    # q1.children.append(('id', 9))    #    # q2 = Q()    # q2.connector = 'OR'    # q2.children.append(('c1', 1))    # q2.children.append(('c1', 10))    # q2.children.append(('c1', 9))    #    # con.add(q1, 'AND')    # con.add(q2, 'AND')    #    # models.Tb1.objects.filter(con)    #    # from django.db import connection    # cursor = connection.cursor()    # cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])    # row = cursor.fetchone()

 

posted on
2017-05-14 19:09 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/yezuhui/p/6853428.html

你可能感兴趣的文章
Maven安装以及为Eclipse指定Maven
查看>>
校园火灾Focue-2---》洗手间的一套-》电梯
查看>>
css控制文字换行
查看>>
ASM的文件管理深入解析
查看>>
bzoj1913
查看>>
烂泥:VMWare Workation双网卡配置IP地址
查看>>
bzoj2301(莫比乌斯反演)
查看>>
【转】对于HttpClient和HtmlUnit的理解
查看>>
L104
查看>>
深入理解脚本化CSS系列第四篇——脚本化样式表
查看>>
分镜头脚本
查看>>
ASP.NET中的cookie编程技术
查看>>
链表基本操作的实现(转)
查看>>
邮件发送1
查看>>
[转] libcurl异步方式使用总结(附流程图)
查看>>
编译安装LNMP
查看>>
git学习,git上建立自己的项目
查看>>
[转]基于display:table的CSS布局
查看>>
企业级 SpringBoot 教程 (二)Spring Boot配置文件详解
查看>>
crm 02--->讲师页面及逻辑
查看>>