关于在Django中,表字段的增删改查,表数据的增删改查,表关系的创建,创建表时的常用字段,及参数。
Django ORM简介
'ORM,对象关系映射'
原理:链式表达式(通过一个对象,可以一直"."出来里面的方法。)
作用:通过'python 面向对象的代码'简单快捷的操作数据库,
不足之处:'封装程度太高 有时候sql语句的效率偏低,需要自己写sql语句'
ORM只能操控到类的级别,要提前创建好库
类 表
对象 记录
对象属性 记录某个字段对应的值
利用ORM创建表
第一步 创建表
from django.db import models
class User(models.Model):
# id int primary_key auto_increment
id = models.AutoField(primary_key=True,verbose_name='主键')
# 主键字段,会自动创建,所以不写也行,在特殊情况下可以自定义主键
# username varchar(32)
username = models.CharField(max_length=32,verbose_name='用户名')
# password int
password = models.IntegerField(verbose_name='密码')
"""
CharField必须要指定max_length参数 不指定会直接报错
verbose_name='用户名' 对字段的解释,该参数是所有字段都有的
orm在不主动定义主键字段的时候,会自动创建一个主键出来
如果主键自己定义了,就不自定义创建了,比如要创建uuid 和aid等
"""
创建表时的常用字段
models.AutoField(primary_key=True) # 主键字段
models.CharField(verbose_name='姓名',max_length=32) # varchar
models.IntegerField() # int
models.BigIntegerField() # bigint
models.DecimalField(max_digits=8,decimal_places=2) # 正数八位,小数2位
email = models.EmailField() # varchar(254) # 邮箱字段
年月日时分秒 models.DateTimeField(auto_now=True) # datetime
年月日 models.DateField(auto_now_add=True) # time
# 参数 auto_now=True :每次修改数据的时候都会自动更新时间
# auto_now_add=True : 只在创建数据的时候,记录创建的时间,后续不会自动修改了,
布尔值 = models.BooleanField() # 布尔值类型
# 该字段传布尔值(false/true) 数据库里面存0/1
fil = models.TextField() # -文本类型
# 该字段可以用来存大段内容(文章,博客..)没有字段限制
# 文章字段用的是TextField
file_path = models.FileField(upload_to='/data') # -文本类型 # 存储的是文件路径,不是文件本身
# 参数 upload_to='/路径' 给该字段传一个文件对象,会自动将文件保存到/data目录下,然后将文件路径保存到数据库中,
# /data/a.txt bbs中会涉及到
创建表时的常用参数
普通表常用参数
ImageField(FileField) 字符串,路径保存在数据库,文件上传到指定目录
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
外键字段常用参数
'外键字段及参数’
null 用于表示某个字段可以为空。
**unique**
ForeignKey(unique=True) === OneToOneFiled() 两者等价 推荐后者,前者也能用
如果设置为unique=True 则该字段在此表中必须是唯一的 。
**db_index** (一般不用写)
如果db_index=True 则代表着为此字段设置索引。
**default**
为该字段设置默认值。
to_field=""
设置要关联的表的字段,默认不写,关联的就是另一张表的主键。
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为
'django2.x以上版本,需要自己指定外键字段的级联更新,级联删除'
**DateField和DateTimeField
auto_now_add
auto_now
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
配置上auto_now=True,每次更新数据记录的时候会更新该字段。
mysql语句与orm语句的对应关系
(mysql 与 orm 的字段对应关系)
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time',
'UUIDField': 'char(32)',
第二步 执行数据库迁移命令
在pycharm中的Terminal中依次输入下面两个命令
python manage.py makemigrations # 将操作记录记录到migrations文件夹
python manage.py migrate # 将操作同步到数据库中(数据库中才会出现表)
简单方法: 在pycharm中
Tools -- Run manage.py Task # 会出现一个终端 ,依次输入 makemigrations migrate
比上面的少输一些代码,并且有自动补全的功能
用ROM实现,字段的增删改查
字段的增加
当表中已经有数据的情况下:
1 可以直接在'终端'内给出默认值
2 直接给字段设置默认值
3 允许字段为空
hobby = models.IntegerField(max_length=32,verbose_name='爱好',default='study')
info = models.CharField(max_length=32,verbose_name='个人简介',null=True)
# 当表中已经数据的情况下,需要考虑新增的字段的 值的问题, 所以新增字段时可以用以下设置
# null = True 该字段可以为空
# default='study' 直接给字段设置默认值
字段的修改
直接修改代码然后执行数据库迁移的命令即可。
字段的删除
把对应的字段注释掉,然后再去执行数据库迁移的命令即可。
执行完毕之后,字段对应的数据也就没有了。
用orm实现,数据的增删改查
添加表数据
# 方式一
res = models.User.objects.create(username='jason', password='123')
print(res) # 返回当前创建的数据对象本身
# 方式二
res = models.User(username='ben', password='123')
res.save()
查询表数据
表数据的查询,可以单条查询,也可以多条查询,(and查询的关系)
单条数据的查询
user_list = models.UserInfo.objects.all()
user_list = models.字段名.objects.all()
# 查字段的所有数据
user_list = models.UserInfo.objects.filter()#本来要加筛选条件的,不加就是所有
userinfo = models.UserInfo.objects.filter(pk=id).first() # 取固定id值的所有数据
userinfo = models.UserInfo.objects.filter(pk=10).first() # 取固定id值的所有数据
根据主键值查询,当然也可以跟其他的 filter(username='xxx') 等
'pk' 是主键值的意思
多条数据的查询
1
res=models.Author.objects.filter(name=username, password=password).all() # 是and查询
2
res=models.Author.objects.filter(name=username, password=password) # 是and查询
3
res=models.Author.objects.filter(name=username).filter(password=password)# 是and查询
4
res=models.Author.objects.filter(name=username, password=password).first() # 是and查询
res=models.Author.objects.create(name=username,password=password)
print(res) # <QuerySet [<Author: Author object>]> QuerySet对象后面可以点出来很多的方法
print(res[0].name)
print(res[0].password)
print(res.name)
print(res.password)
Queryset对象支持索引和切片操作,但是不支持负数索引的操作
修改表数据
'方法一:'
age = request.POST.get('age')
gender = request.POST.get('gender') '得到数据'
userinfo.age = age '修改数据'
userinfo.gender = gender
userinfo.save() *****'保存数据'*****
'方法二:'
res = models.UserInfo.objects.filter(pk=1).update(age=age,gender=gender)
eg: res = models.UserInfo.objects.filter(pk=1).update(age=18,gender='男')
'pk是主键的意思',
删除表数据
'方法一'
models.UserInfo.objects.filter(pk=id).delete()
# 通过值操作,删除一个数据的sql语句
'方法二'
object = models.UserInfo.objects.filter(pk=id).first()
object.delete() # 先到数据库查询,得到一个对象,然后再删除。
diango orm 中如何创建表关系
创建表关系,先将基表创建出来,然后再添加外键字段
表与表的关系
'一对一'
'一对多'
'多对多'
这里以图书表,出版社表,作者表,作者详情表,为例
首先,梳理出来表关系
这里用图书表,出版社表,作者表,作者详情表来做例子
# 图书和出版社是一对多的关系
外键字段建在查询多的一方 book
#书和作者是多对多的关系
需要创建第三张表 可以自动创建也可以手动创建
# 作者与作者详情表是一对一
判断表关系的方法:换位思考
创建表关系,首先要将基表创建出来,然后再添加外键字段
一对一的关系,外键字段创建在查询比较多的表多
一对多的关系,外键字段创建在查询比较多的表中
多对多的关系,可以自动创建第三张表,也可以手动创建第三张表。
* 一对多,多对多
models.ForeignKey()
models.ManyToMany()
from django.db import models
class Book(models.Model): # 书籍表
title = models.CharField(max_length=32) # 字符串类型
price = models.DecimalField(max_digits=8, decimal_places=2)
# 总共八位数,小数点后面占两位
"""
图书和出版社是一对多,并且书是多的一方,所以外键字段放在book表中
"""
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE) # 一对多
# 默认和出版社表的主键字段做外键关联 一对多,
"""
图书和作者是多对多的关系,外键字段建在任意一方均可,但是推荐建在查询频率较高的一方
原生mysql需要手动创建,现在orm会自动创建出来第三张表(自动创建扩展性差,可以手动创建)
"""
authors = models.ManyToManyField(to='Author',on_delete=models.CASCADE) # 多对多
# authors是一个虚拟字段,主要用来告诉orm 书籍表和作者表是多对多的关系。
# 让orm自动创建第三张关系表
一对一
models.OneToOneField()
class Publish(models.Model): # 出版社
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
class Author(models.Model): # 作者表
name = models.CharField(max_length=32)
age = models.IntegerField()
author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
"""
作者与作者详情是一对一的关系 外键字段建在任意一方都可以
推荐建立在查询频率高的一方
"""
# OneToOneField 也会自动给字段添加_id后缀
class AuthorDetail(models.Model): # 作者详情
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
"""
创建表关系的总结
orm中如何定义三种关系
publish = models.ForeignKey(to='xxx') # 一对多
authors = models.ManyToManyField(to='xxx') # 多对多
author_detail =models.OneToOneField(to='xxx') # 一对一
ForeignKey 和 OneToOneField 在创建外键关系时,会自动在字段后面加_id后缀
ManyToManyField 会自动创建第三张表,是虚拟表
"""
# 在 django1.x版本中,外键默认都是级联更新删除,不需要额外加on_delete参数
# 在 djangp2.x版本中,外键不是默认级联更新删除,所以要加on_delete=models.CASCADE 参数
# 多对多的表关系可以有好几种创建方式
多对多表关系的三种创建方式
1全自动
在表关系及其简单的项目中,才用这种方法。
# 全自动 (利用orm自动的帮我们创建第三张关系表)
class Book(models.Model):
name = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author')
class Author(models.Model):
name = models.CharField(max_length=32)
"""
优点:代码不要写,非常方便,并且支持orm提供的操作第三张表的方法
add remove clear 正反向查询....等等
不足之处: 第三张关系表的扩展性极差(没有办法额外添加字段)
"""
在表关系及其简单的项目中,才用这种方法
2 纯手动
自己创建第三张表,手动写表之间的关系
class Book(models.Model):
name = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
class Book2Author(models.Model):
book_id = models.ForeignKey(to='Book')
author_id = models.ForeignKey(to='Author')
"""
优点: 第三张表完全取决于自己,可以进行额外的扩展
缺点: 需要写的代码较多,不能够使用orm提供的简单的orm方法
add remove clear 正反向查询....等等 都没法用
**不建议使用该方式
"""
3 半自动
需要掌握全自动和半自动
全自动方便 简单的表关系可以用
半自动扩展性极高 最合理 用处最大 平时用的最多 。
# 半自动
class Book(models.Model):
name = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author',
through='Book2Author', # 告诉orm我自己创建的表
through_fields=('book', 'author') #用哪两个字段绑定关系
)# 告诉orm我通过哪两个字段绑定关系
# through='Book2Author' 告诉orm我和Author是多对多的关系,我是通过我自己写的表来创建关系的
# through_fields=('book','author') 告诉orm 我是通过哪两个字段绑定关系的
class Author(models.Model):
name = models.CharField(max_length=32)
'多对多的外键字段可以创建在任意一张表中,但创一个就够了。'
class Book2Author(models.Model):
book = models.ForeignKey(to='Book') # orm会自动在外键字段后面加_id
author = models.ForeignKey(to='Author')
"""
through_fields=('xxxx', 'oooo')
判断的本质:
通过第三张表查询对应的表,需要用到哪个字段,就把哪个字段放在前面。
简化判断:
当前的表是谁,就把对应的表放在前面
半自动: 可以使用orm的正反向查询,但是没法使用add,set,remove,clear这四个方法
"""