ORM概念:

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象(

1. 不同的程序员写的SQL水平参差不齐
2. 执行效率也参差不齐

)的技术。

ORM 能够把 python语句 自动的翻译 为SQL语句

ORM优点: 

  1. 简单,不用自己写SQL语句
  2. 开发效率高

  缺点:

  执行效率有差距 

ORM的对应关系:

  类 ---> 数据表
  对象 ---> 数据行
  属性 ---> 字段

ORM能做的事儿:
  1. 操作数据表 --> 创建表/删除表/修改表
      操作models.py里面的类

  2. 操作数据行 --> 数据的增删改查

  不能创建数据库,自己动手创建数据库

使用Django的ORM详细步骤:
1. 自己动手创建数据库
  create database 数据库名;
2. 在Django项目中设置连接数据库的相关配置(告诉Django连接哪一个数据库)
  # 数据库相关的配置
  DATABASES = {
  'default': {
  'ENGINE': 'django.db.backends.mysql', # 连接的数据库类型
  'HOST': '127.0.0.1', # 连接数据库的地址
  'PORT': 3306, # 端口
  'NAME': "day61", # 数据库名称
  'USER': 'root', # 用户
  'PASSWORD': '123456' # 密码
  }
  }

3. 告诉Django用pymysql代替默认的MySQLDB 连接MySQL数据库
  在项目/__init__.py文件中,写下面两句:
  import pymysql
  # 告诉Django用pymysql来代替默认的MySQLdb
  pymysql.install_as_MySQLdb()

4. 在app/models.py里面定义类
# 出版社
class Publisher(models.Model):
id = models.AutoField(primary_key=True) # 自增的ID主键
# 创建一个varchar(64)的唯一的不为空的字段
name = models.CharField(max_length=64, null=False, unique=True)

5. 执行两个命令
1. python3 manage.py makemigrations --> 把models.py里面的更改记录到小本本上
2. python3 manage.py migrate --> 把更改翻译成SQL语句,去数据库执行

Django ORM常用字段:
  1. AutoField --> 自增
  2. CharField --> varchar(xx)
  3. ForeignKey --> 外键

    ForeignKey 字段的参数;

    a.to  --> 设置要关联的表;

    b.to_field -->设置要关联的表的字段

    c.related_name -->  反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。
  4. ManyToManyField --> 多对多关联

  5. DateField  -->日期字段,日期格式  YYYY-MM-DD 
  6. DateTimeField --> 日期时间字段,格式 YYYY-MM-DD HH:MM

  7. IntegerField -->整数类型

字段的合集:

AutoField(Field)
- int自增列,必须填入参数 primary_key=True BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32) class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647 BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 BooleanField(Field)
- 布尔值类型 NullBooleanField(Field):
- 可以为空的布尔值 CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度 TextField(Field)
- 文本类型 EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制 GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both" URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号) CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字 UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹 FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串) DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field)
- 浮点型 DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度 BinaryField(Field)
- 二进制类型 字段合集

 

在ORM 表单中没有char字段;需要自定义

#自定义char字段
class FixedCharField(models.Field):
"""
自定义的char类型的字段类
""" def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return 'char(%s)' % self.max_length
class Class(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=25)
# 使用上面自定义的char类型的字段
cname = FixedCharField(max_length=25)

  

3. 常用的字段参数
1. null

用于表示某个字段可以为空。
2. default

该字段为默认值
3. unique

如果设置为unique=True 则该字段在此表中必须是唯一的 。
4. db_index
如果db_index=True 则代表着为此字段设置数据库索引。

5. DateField和DateTimeField才有的参数:
auto_now_add=True --> 创建数据的时候自动把当前时间赋值
auto_add=True --> 每次更新数据的时候更新当前时间
上述两个不能同时设置!!!

  

表和表之间的关系
1. 一对多(出版社和书);1对多  ,外键通常设置在多的那一边;
publisher = models.ForeignKey(to="Publisher")
数据库中实际 生成的是一个 publisher_id 字段

2. 多对多(作者和书);多对多,通常设置在正向查询多的那一边;比如我用author 查询 book 比较多,则把外键放在author.
books = models.ManyToManyField(to="Book")

在数据库中:
是通过第三张表建立的关系(默认第三张表名 为字段_另一个多对多的字段)

# 书
class Book(models.Model):
id = models.AutoField(primary_key=True)
bookname = models.CharField(null=False,max_length=15,unique=True)
price = models.DecimalField(max_digits=5,decimal_places=2,default=99.99)
kucun = models.IntegerField(default=10000)
sell_num = models.IntegerField(default=0)
# 书和出版社关联的外键(单表对单表的)
# on_delete=models.CASCADE ; 级联删除,即删除主表数据会自动删除从表数据;使关联的数据对应;
# related_name 来代替 表名_set;
publisher = models.ForeignKey(to="Publisher",default=1,on_delete=models.CASCADE,
     related_name='books')
     #反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。
#在数据库里面生成的字段为 publisher_id 是出版社的id
#Book.object.publisher 为该书对应的出版社的对象;
def __str__(self):
return "Publisher_object:{}".format(self.bookname) #出版社
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(null=False,max_length=15,unique=True) def __str__(self):
return "Publisher_object:{}".format(self.name) # class Meta:
# ordering ='id' # 书和出版社是,1对1的(ForeignKey(to=)),是需要添加外键的 # 而书和作者是多对多的,一本书可以有多个作者,还有一个作者也可能有多本书,即多对多的时候用(ManyToManyField(to=))
#然后ROM会自动的帮你生成另外的一张表来表示多对多的关系,这个列子生产的另外一个表为author_book;
# 作者
class Author(models.Model):
id = models.AutoField(primary_key=True)
author_name = models.CharField(null=False, max_length=15)
#多对多的
book = models.ManyToManyField(to="Book") def __str__(self):
return "Publisher_object:{}".format(self.author_name)

 详细参考(点我) 

3. 一对一  ;比如作者和作者详情,一个作者只能对于自己的作者详情;

1. 什么时候用一对一?
  当 一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁
  把不怎么常用的字段 单独拿出来做成一张表 然后用过一对一关联起来
2. 优势
  既保证数据都完整的保存下来,又能保证大部分的检索更
3. ORM中的用法
  OneToOneField(to="")

举例:作者和作者详情是一对一的;跟一对多,用法相同,只不过detail里面的不能重复;在数据库中也是多一个detail_id 字段

总结+练习ORM(多表的查询)

	# #####################基于对象查询(子查询)##############################
# 按字段(publish)
# 一对多 book -----------------> publish
# <----------------
# book_set.all() # 正向查询按字段: # 查询python这本书籍的出版社的邮箱 # python=models.Book.objects.filter(title="python").first()
# print(python.publish.email) # 反向查询按 表名小写_set.all() # 苹果出版社出版的书籍名称 # publish_obj=models.Publish.objects.filter(name="苹果出版社").first()
# for obj in publish_obj.book_set.all():
# print(obj.title) # 按字段(authors.all())
# 多对多 book -----------------------> author
# <----------------
# book_set.all() # 查询python作者的年龄
# python = models.Book.objects.filter(title="python").first()
# for author in python.authors.all():
# print(author.name ,author.age) # 查询alex出版过的书籍名称 # alex=models.Author.objects.filter(name="alex").first()
# for book in alex.book_set.all():
# print(book.title) # 按字段 authorDetail
# 一对一 author -----------------------> authordetail
# <----------------
# 按表名 author # 查询alex的手机号
# alex=models.Author.objects.filter(name='alex').first()
# print(alex.authorDetail.telephone) # 查询家在山东的作者名字 # ad_list=models.AuthorDetail.objects.filter(addr="shandong")
#
# for ad in ad_list:
# print(ad.author.name) '''
对应sql: select publish_id from Book where title="python"
select email from Publish where nid = 1 ''' # #####################基于queryset和__查询(join查询)############################ # 正向查询:按字段 反向查询:表名小写 # 查询python这本书籍的出版社的邮箱
# ret=models.Book.objects.filter(title="python").values("publish__email")
# print(ret.query) '''
select publish.email from Book
left join Publish on book.publish_id=publish.nid
where book.title="python"
''' # 苹果出版社出版的书籍名称
# 方式1:
# ret1 = models.Publish.objects.filter(name="苹果出版社").values("book__title")
# print("111111111====>", ret1.query)
# # 方式2:
# ret2 = models.Book.objects.filter(publish__name="苹果出版社").values("title")
# print("2222222222====>", ret2.query)
#
# # 查询alex的手机号
# # 方式1:
# ret = models.Author.objects.filter(name="alex").values("authorDetail__telephone")
#
# # 方式2:
# models.AuthorDetail.objects.filter(author__name="alex").values("telephone") # 查询手机号以151开头的作者出版过的书籍名称以及书籍对应的出版社名称 ; 跨5张表; 都联合起来;
ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values('title', "publish__name")
print(ret)

  

# 作者
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
phone = models.IntegerField()
books = models.ManyToManyField(to="Book", related_name="authors")
detail = models.OneToOneField(to="AuthorDetail") def __str__(self):
return self.name # 作者详情
class AuthorDetail(models.Model):
# 爱好
hobby = models.CharField(max_length=32)
# 地址
addr = models.CharField(max_length=128)  

Django基础——ORM字段和字段参数的更多相关文章

  1. 6月20日 Django中ORM介绍和字段、字段参数、相关操作

    一.Django中ORM介绍和字段及字段参数 二.Django ORM 常用字段和参数 三.Django ORM执行原生SQL.在Python脚本中调用Django环境.Django终端打印SQL语句 ...

  2. Django中ORM介绍和字段及其参数

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  3. Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM)

    Django中ORM介绍和字段及字段参数   Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...

  4. Django中ORM介绍和字段

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  5. Django中ORM介绍和字段及字段参数

    Object Relational Mapping(ORM) 1 ORM介绍 1.1 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对 ...

  6. Django中ORM介绍和字段参数

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  7. django【ORM】model字段类型

    1.AutoField 一个自增的IntegerField,一般不直接使用,Django会自动给每张表添加一个自增的primary key. 2.BigIntegerField 64位整数, -922 ...

  8. Django基础(ORM)

    数据库与ORM 数据库的配置 1    django默认支持sqlite,mysql, oracle,postgresql数据库.  <1> sqlite django默认使用sqlite ...

  9. Django 基础 ORM系统

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

随机推荐

  1. 10.04 FZSZ模拟Day1 总结

    今天轮到FZSZ出题了,这可是连续两年捧杯NOI的学校了…… 可想而知今天题难度有多大……不过似乎还要庆幸出题的是一位叫Anzhe Wang 的大神而不是fjzzq? T1.permutation 期 ...

  2. Python基础第二天

    一.内容 二.练习 练习1 题目:已知msg='hello knight 666'编写for循环,利用索引遍历出每一个字符 图示: 代码: msg = 'hello knight 666' msg_l ...

  3. jQuery中contains和has的区别

    jQuery中contains和has的区别 根据不同的内容和属性可以准确定位到需要找的属性 如何根据内容筛选标签?:contains        匹配包含给定的文本元素$("div:co ...

  4. SSM整合配置错误记录

    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dic ...

  5. 为什么JavaWeb项目要分层

    首先让我们坐着时光机回到n年前的web开发.那个时候最早都是静态的html页面,后来有了数据库,有了所谓的动态页面,然后程序猿在编码的时候,会把所有的代码都写在页面上,包括数据库连接,包括事务控制,接 ...

  6. 关于Webpack的的认识及傻瓜式教学

    刚学习了Webpack,ememememememememem就赶脚是一个打包工具,将js.css.json.img等等通通打包为最终的文件,最后渲染为一个页面. 也是终于捋清了Webpack的思路,在 ...

  7. 面试官:聊一下你对MySQL索引实现原理?

    在数据库中,如果索引太多,应用程序的性能可能会受到影响,如果索引太少,又会对查询性能产生影响.所以,我们要追求两者的一个平衡点,足够多的索引带来查询性能提高,又不因为索引过多导致修改数据等操作时负载过 ...

  8. 数据传递-------@ResponseBody

    1.导入jar包 jack-core-asl-1.9.11.jar jack-mapper-asl-1.9.11.jar 2.配置springmvc-servlet.xml文件 <?xml ve ...

  9. Python Turtle绘图

    1. 画布(canvas) 画布就是turtle为我们展开用于绘图区域, 我们可以设置它的大小和初始位置 1.1 设置画布大小 turtle.screensize(canvwidth=None, ca ...

  10. SQL server中的T-SQL语句

    首先点击新建查询 如下图所示 创建数据库:create database 数据库名称 使用数据库:use 数据库名称 创建表:create table 表名 ( 代码 ) 输入完成执行时需选中 如果需 ...