django的ORM系统

ORM概念:对象关系映射(Object Relational Mapping,简称ORM)
ORM的优势:不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。

  • 模型类必须都写在app下的models.py文件中
  • 模型如果需要映射到数据库,所在的app必须被安装
  • 一个数据表对应一个模型类,表中的字段,对应模型中的类属性

 配置数据库

1.在settingss.py里面配置DATABASSES

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'NAME': 'mydb', #数据库名称
'USER': 'admin', # 链接数据库的用户名
'PASSWORD': 'Root110qwe', # 链接数据库的密码
'HOST': '127.0.0.1', # mysql服务器的域名和ip地址
'PORT': '', # mysql的一个端口号,默认是3306
}
}

2.设置连接器

需要安装pymysql,安装方法不再赘述

在主目录下创建 __init__.py 文件,写入如下两行代码

import pymysql
pymysql.install_as_MySQLdb() #将pymysql作为连接器

一、模型数据表的创建

1.在对应的APP目录的 models.py定义模型类,即建表

#创建一个数据表
class Demo(models.Model):
id = models.AutoField(primary_key=True) #设置为主键
name = models.CharField(max_length=30) #添加一个name的字段
age = models.IntegerField() #添加一个age的字段

2.映射数据库

法一

找到 Tools 下面的 Run manage.py Task

生成文件映射 makemigrations ,后跟APP名,如果不指定,则全部添加;

将映射提交到数据库 migrate

法二

在SSH里执行命令 python manage.py makemigration 和 python manage.py migrate

3.检查

可以看到,里面成功创建了 db_test_demo ( 数据库表名 = APP名_模型类名 )的数据表,其他的是django自带

看一下设计结构

二、数据的常规操作

以下数据的操作是使用视图函数,通过访问url来调用函数,视图函数和路由配置不再赘述,只展示视图函数的函数体部分

1.插入

 法一

Chancey = Demo(name='Chancey',age=18)
Chancey.save()

法二

Chancey = Demo()
Chancey.name = 'Chancey'
Chancey.age = 18
Chancey.save()

法三

Demo.objects.create(name='Chancey',age=18)

法四

Demo.objects.get_or_create(name='Chancey',age=18)

这时,在访问URL的时候报错

大致意思是,什么什么三个了,回到数据库看一下

发现也没有成功插入数据

这是因为该方法不会重复添加相同的数据,这里随便改一下

Demo.objects.get_or_create(name='Make',age=20)

成功添加

2.查询

查询之前需要添加一个 __str__ 的魔术方法,以格式化输出

def __str__(self):
return 'Demo<id=%s,name=%s,age=%s>'%(self.id,self.name,self.age)

法一(get)

rs = Demo.objects.get(name='Make')
print(rs)

这里返回的是一个实例对象,且get方法查找只能查找条件唯一的数据

法二(filter)

rs = Demo.objects.filter(name='Chancey')
print(rs)

控制台可以看到 <QuerySet [<Demo: Demo<id=1,name=Chancey,age=18>>, <Demo: Demo<id=2,name=Chancey,age=18>>, <Demo: Demo<id=3,name=Chancey,age=18>>]> ,这是一个类似于集合的Query_Set对象,该对象可迭代、可被构造、可过滤、可切片、可被作为参数传递。

法三(all)

rs = Demo.objects.all()
print(rs)

查询所有,不再赘述

3.更改

法一

rs = Demo.objects.get(name='Make') #获取类的属性
rs.name = 'Mary' #修改类的属性
rs.save() #记得保存

法二

Demo.objects.filter(name='Mary').update(name='Make')   #最容易理解

法三

添加新的字段可以在定义模型类里面添加,这会改变表的结构

添加之后重新生成映射文件并且提交到数据库

4.删除

Demo.objects.filter(name='Chancey').delete()

三、常用的查询

常用的查询方法

  1. 获取所有记录 rs = Demo.objects.all()
  2. 获取第一条数据 rs = Demo.objects.first() last亦然,即最后一条数据
  3. 指定条件 rs = Demo.objects.filter(name='Make',age=20)
  4. 指定条件 rs = Demo.objects.get(name='Chancey') 和filter的区别就是get指定的条件只能是唯一的
  5. 排除条件  rs = Demo.objects.exclude(name='Chancey')
  6. 排序 rs = Demo.objects.order_by('age') #按照指定条件进行排序,反向前加'-'即可
  7. 将返回的对象转换成字典 rs = Demo.objects.all().values() 既然Sery_Set对象可跌,转换成字典意义不大
  8. 获取当前查询的总数量 rs = Demo.objects.count()

常用的查询条件

内容非常简单,不再详述其用法

四、常用字段及参数

常用的字段类型对应到mysql的关系

1. IntegerField : 整型,映射到数据库中的int类型。

2. CharField: 字符类型,映射到数据库中的varchar类型,通过max_length指定最大长度。

3. TextField: 文本类型,映射到数据库中的text类型。

4. BooleanField: 布尔类型,映射到数据库中的tinyint类型,在使用的时候,传递True/False进去。如果要可以为空,则用NullBooleanField。

5. DateField: 日期类型,没有时间。映射到数据库中是date类型, 在使用的时候,可以设置DateField.auto_now每次保存对象时,自动设置该字段为当前时间。设置DateField.auto_now_add当对象第一次被创建时自动设置当前时间。

6. DateTimeField: 日期时间类型。映射到数据库中的是datetime类型, 在使用的时候,传递datetime.datetime()进去。

常用的参数

primary_key: 指定是否为主键。

unique: 指定是否唯一。

null: 指定是否为空,默认为False。

blank: 等于True时form表单验证时可以为空,默认为False。

default: 设置默认值。

DateField.auto_now: 每次修改都会将当前时间更新进去,只有调用,QuerySet.update方法将不会调用。这个参数只是Date和DateTime以及TimModel.save()方法才会调用e类才有的。

DateField.auto_now_add: 第一次添加进去,都会将当前时间设置进去。以后修改,不会修改这个值

五、表关系

Django里面已经封装好了诸多方法,只需要调用即可

举个例子,现在需要实现如下表关系,对于mysql层面上的表关系不太理解的可以去数据库栏目里

可以点击下载附件

分析以上表关系,可以总结出

现在映射到模型

建表

实现一对多(即学院信息表和学生信息表)

#创建学院信息表
class Department(models.Model):
d_id = models.AutoField(primary_key=True)
d_name = models.CharField(max_length=30) def __str__(self):
return 'Department<d_id=%s,d_name=%s>'%(self.d_id,self.d_name) #创建学生信息表
class Student(models.Model):
s_id = models.AutoField(primary_key=True)
s_name = models.CharField(max_length=30)
department = models.ForeignKey('Department',on_delete=models.CASCADE) #这里的on_delete是级联删除 def __str__(self):
return 'Student<s_id=%s,s_name=%s>'%(self.s_id,self.s_name)

之后还是原来的套路,即 makemigrations 和 migrate

可以看到,直接用 models.ForeignKey 即可完成外键关联

再来数据库里面看看

查看下表结构

 实现一对一(创建学生详情表,和学生信息表一对一)

class Student_detail(models.Model):
student = models.OneToOneField('Student',on_delete=models.CASCADE) #一对一的关系,主从不影响
gender = models.BooleanField(default=True)
height = models.IntegerField()
wight = models.IntegerField()

查看表结构

实现多对多(创建课程表,和学生信息表多对多)

class Course(models.Model):
c_id = models.AutoField(primary_key=True)
c_name = models.CharField(max_length=30)
student = models.ManyToManyField('Student')

查看数据库

不难发现,这里多出来了 db_test_course 和 db_test_course_student

这里不用自行创建中间信息表,Django会自动创建中间信息表

看下两张表的结构

六、表关联对象的访问

 一对多关系

先给 department 表插入数据(只写函数体部分,这种方法是通过视图函数来使用,所以必须分配路由并返回response对象)

    Department.objects.create(d_name='信息工程')
Department.objects.create(d_name='经济管理')
Department.objects.create(d_name='纺织服装')
Department.objects.create(d_name='艺术传媒')
Department.objects.create(d_name='商务外语')

查询

d1 = Department.objects.get(d_id=1)
s1 = Student.objects.get(s_id=1)
print(s1.department.d_name) #正向查询,查该生的所属学院
print(d1.student_set.all()) #反向查询,用_set做管理器,查这个学院的学

可以在定义时设置related_name 参数来覆盖foo_set 的名称

  • 1.d1.student的管理器有add的方法.
  • 2.例子中的s2能添加成功是因为设置了student表中department字段允许为空了

一对一关系

    std = Student_detail.objects.get(id=2)
print(std.student.s_name) #正向查询,查这个学生的名字
print(s1.student_detail.age) #反向查询,查年龄

注意对于所有类型的关联字段,add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法

八、多表查询

    print(Student.objects.filter(department_id=2))  #查询学院的所有学生
print(Student.objects.filter(course__c_id=1)) #查询选该课程的所有学生
print(Department.objects.filter(student__s_name__contains='何')) #查询名字里包含‘何字’的学生的学院
print(Course.objects.filter(student__s_id=1.all())) #查询学号为1的学生所选的课程
print(Student.objects.filter(course__c_id=1).all()) #查询课程1报名的同学
print(Department.objects.filter(student__course__c_id=1)) #查询报名了某课程的学生的学院

Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段

模型model的更多相关文章

  1. ASP.NET MVC在布局页上使用模型(model)

    看到这标题有点怪,一般情况之下,我们很容易在视图与部分视图中使用模型(model),但是如果想在布局页_Layout.cshtml页中使用模型(model),按照普通方式也许没有达到预期的效果,在实现 ...

  2. 【再探backbone 01】模型-Model

    前言 点保存时候不注意发出来了,有需要的朋友将就看吧,还在更新...... 几个月前学习了一下backbone,这段时间也用了下,感觉之前对backbone的学习很是基础,前几天有个园友问我如何将路由 ...

  3. ThinkPHP 模型(Model)命名规范

    一个小问题搞了好久:如果数据库的表名中有下划线,那么在用thinkphp做自动完成时注意Model类的命名要变成驼峰法,文件名和类名都要变.( 另外注意:只有使用create方法创建数据时才能调用到自 ...

  4. laravel之模型Model

    模型Model: 在控制器中调用:

  5. 利用libsvm-mat建立分类模型model参数解密[zz from faruto]

    本帖子主要就是讲解利用libsvm-mat工具箱建立分类(回归模型)后,得到的模型model里面参数的意义都是神马?以及如果通过model得到相应模型的表达式,这里主要以分类问题为例子. 测试数据使用 ...

  6. C#-MVC基础-模型(Model)、视图(View)和控制器(Controller)

    搜狗百科:http://baike.sogou.com/v25227.htm?fromTitle=MVC MVC全名是Model View Controller,是软件工程中的一种软件架构模式,把软件 ...

  7. Thinkphp5.0 的使用模型Model的获取器与修改器

    Thinkphp5.0 的使用模型Model的获取器.修改器.软删除 一.获取器 在model中使用 get+字段名+Attr,可以修改字段的返回值. 数据库中性别保存为,0未知.1男.2女,查询时返 ...

  8. Thinkphp5.0 的使用模型Model删除数据

    Thinkphp5.0 的使用模型Model删除数据 一.使用destory()删除数据 //删除id为3的记录 $res = User::destroy(3); //返回影响的行数 dump($re ...

  9. Thinkphp5.0 的使用模型Model更新数据

    Thinkphp5.0 的使用模型Model更新数据 (1)使用update()方法进行更新数据 一.where条件写在更新数据中 (这种情况更新的数据,必须含主键) $res = User::upd ...

  10. Thinkphp5.0 的使用模型Model添加数据

    Thinkphp5.0 的使用模型Model添加数据 使用create()方法添加数据 $res = TestUser::create([ 'name' => 'zhao liu', 'pass ...

随机推荐

  1. ubuntu 16.04快速安装ceph集群

    准备工作 假设集群: 选一台作管理机 注意: ceph集群引用hostname,而非ip. 172.17.4.16 test16 #hostname必须是test16 172.17.4.17 test ...

  2. WCF服务的IIS托管(网站托管)

    基本思路 1.新建WCF应用程序2.注册路由(可省略,则用/….svc/….访问)配置文件 <appSettings> <add key="aspnet:UseTaskFr ...

  3. windows server疑难杂症

    1.某些网址.服务访问失败,可能的原因:增强的安全配置关闭增强的安全配置,并且重启电脑!!!http://jingyan.baidu.com/article/6181c3e076ac0b152ff15 ...

  4. DotNetBar for Windows Forms 14.0.0.3_冰河之刃重打包版原创发布

    关于 DotNetBar for Windows Forms 14.0.0.3_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  5. QTextStream 居然接受FILE*这样的传统参数

    实在是太爽.太牛了,无话可说-

  6. 微信小程序把玩(七)数据绑定

    原文:微信小程序把玩(七)数据绑定 数据绑定有一部分前几个看着还行,后面的几个可能有几个不理解,界面展示的数据有的也因为条件没法显示.看不懂的可以先记着,后面真正用到时就会明白,反正我是这样想的.这里 ...

  7. mysqldump数据库备份与恢复

    mysqldump -u 用户名 -p 数据库名> 备份的文件名 本文中因服务器为多实例,所以在执行登陆等命令时指定了-S参数,即指定其中一个数据库 备份: mysqldump -u root ...

  8. List<T>多字段排序的一个通用类

    本文中的方法旨在解决通用的问题,非常注重效率的地方,还应该针对具体的类去写排序方法. 废话不多说,直接上代码 具体使用场景: 要排序的类 1 public class bb 2 { 3 public ...

  9. Android进程间通信-AIDL实现原理

    Android进程间通信基于Proxy(代理)与Stub(桩或存根)的设计模式(如图1-1所示).其中,Proxy将特殊性接口转换成通用性接口,Stub将通用性接口转换成特殊性接口,二者之间的数据转换 ...

  10. WCSTOMBS 函数不支持中文件的解决方法(设置代码页)

    代码页没有进行设置.需要调用locale.h 中定义的一个函数设置默认的代码页 _tsetlocale(LC_ALL,_T(""));//设置代码页  wcstombs(sendB ...