关于Django ORM全面的记录(操作数据库)

关于在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这四个方法
"""

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值