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. 【LeetCode】LRU Cache 解决报告

    插话:只写了几个连续的博客,博客排名不再是实际"远在千里之外"该.我们已经进入2一万内. 再接再厉.油! Design and implement a data structure ...

  2. Gtk+/Gtkmm介绍与安装(有继承关系图)

    GTK+是一套跨平台的,以C语言编写的GUI类库,它起源于GNU的图像处理程序"GIMP",因而被起名为"The GIMP Toolkit",从一开始它就被设计 ...

  3. 大约Android远程监控APP源代码

    这篇文章的目的,关心询问名人,要打开源代码.这里说明,远程监控摄像头场外,相反,用手机摄像头摄像头server上,要理解这一点.关于非常网上的文章达到server道路.它能够准确,念就乱发博文,当然假 ...

  4. C/C++使用libcurl库发送http请求(get和post可以用于请求html信息,也可以请求xml和json等串)

    C++要实现http网络连接,需要借助第三方库,libcurl使用起来还是很方便的 环境:win32 + vs2015 如果要在Linux下使用,基本同理 1,下载编译libcurl 下载curl源码 ...

  5. C#/WPF 计算字串的真实长度,调整控件的宽度

    下面函数是经常用到的计算字串长度的方法:         private double MeasureTextWidth(String str, string fontName, double fon ...

  6. 【转】编程之道 之 Rob Pike

    1.你无法断定程序会在什么地方耗费运行时间.瓶颈经常出现在想不到的地方,所以别急于胡乱找个地方改代码,除非你已经证实那儿就是瓶颈所在. 2.估量.在你没对代码进行估量,特别是没找到最耗时的那部分之前, ...

  7. Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

    原文:Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅 在前几期中总结分享了Android的前世今生.Android 系统架构和应用组件那些事.带你一起来聊一聊Android开发 ...

  8. Morris 轻量级 图表

    Morris.js 是基于 jQuery 和 Raphaël 的轻量级矢量图形库,帮助开发人员轻松绘制各种形式的图表.示例: HTML: <div id="myfirstchart&q ...

  9. Linux文件系统操作与磁盘管理

    简单文件操作 df---->report file system disk space usage du---->estimate file space usage 2.简单的磁盘管理 d ...

  10. 关于联合体union的详细解释

    1.概述 联合体union的定义方式与结构体一样,但是二者有根本区别. 在结构中各成员有各自的内存空间,一个结构变量的总长度是各成员长度之和.而在“联合”中,各成员共享一段内存空间,一个联合变量的长度 ...