Django中级篇之Model专题
Posted 叶祖辉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django中级篇之Model专题相关的知识,希望对你有一定的参考价值。
ORM
就是用面向对象的方式去操作数据库的创建表以及增删改查等操作
到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:
- 创建数据库,设计表结构和字段
- 使用 mysqldb 来连接数据库,并编写数据访问层代码
- 业务逻辑层去调用数据访问层执行数据库操作
django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM)
一、创建表
1、基本结构
注意:
1、创建表的时候,如果我们不给表加自增列,生成表的时候会默认给我们生成一列为ID的自增列,当然我们也可以自定义
2、如果我们给某一列设置了外键的时候,生成表的时候,该列的表名会自动生成auter_id(即俩个字段中间用_连接起来)
3、创建外键的时候 models.ForeignKey(UserType) ForeignKey中参数代表的类必须在其上面,否则就必须写成字符串的形式
from django.db import models class 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\') ]
通过内部类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) ------------------------------------------------------------------------------------------------------------------------------------------------------ <class \'app1.models.UserType\'> UserType object <class \'app1.models.UserType\'> UserType object <class \'app1.models.UserType\'> UserType object <class \'django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager\'> app1.UserInfo.None <class \'django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager\'> app1.UserInfo.None <class \'django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.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()
3、自己创第三种表+ManyToManyField()-----虽然这样看起来后面的在创建数据库的时候没用,但是其在操作数据库的时候有用
中间模型表如果是通过through制定的,add create方法会失效
慎用: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()
以上是关于Django中级篇之Model专题的主要内容,如果未能解决你的问题,请参考以下文章
[AngularJS] AngularJS系列 中级篇之指令
Python+Selenium中级篇之2-Python中类/函数/模块的简单介绍和方法调用
Python+Selenium中级篇之8-Python中的继承的使用