三尺非寒 发表于 2024-8-1 15:25:08

Django之数据库篇(Python)

#媒介:

关于Django我在此片博客之前已经发布了六篇博客,感爱好的可以在主页查察学习与交换。此篇博客我会解说在Django中数据库的一些操作,如若各位大佬发现错误大概需要添加的内容,欢迎各位指正,最后我后续还会继承更新关于Django的一些基本内容,欢迎各人关注。
一、数据库及其在开发中的职位介绍:

关于数据库,最简单最浅显的认知就是它是用来存储数据和管理数据的一门学科,但是关于数据库的认知可不止云云。
1.数据库体系(DBS):

从广义上来讲数据库体系它由四部门组成,分别是数据库、硬件、软件、人员组成。而数据库体系它是采用了数据库技能,有构造地、动态的存储大量数据,方便用户访问的盘算机体系。
注意:数据库属于数据库体系。
1、数据库:

数据库是统一管理的、恒久储存在盘算机内的、有构造的相干数据的聚集。其特点是数据间联系密切、冗余度小、独立性较高、易扩展,并且可为各类用户共享。
2、硬件:

硬件是构成盘算机体系的各种物理设备,包括存储数据所需的外部设备。硬件的配置应满足整个数据库体系的需要。
3、软件:

软件包括操作体系、数据库管理体系及应用程序。此中数据库管理体系是最为重要的一个点,也是数据库这门学科中的焦点内容。数据库管理体系它是数据库体系的焦点软件,需要在操作体系的支持下工作,解决如何科学地构造和储存数据。
4、人员:

人员主要有4类。
第一类为体系分析员和数据库设计人员,体系分析员负责成用体系的需求分析和规范说明,他们和用户及数据库管理员一起确定体系的硬件配置,并参数据库体系的概要设计。
第一类为应用程序员,负责编写利用数据库的应用程序,这些应用程序可对数据进行检索、创建、删除或修改。
第三类为终极用户,他们应用体系的接口或利用查询语言访问数据库。
第类用户是数据库管理员(Data Base Administrator,DBA),负责数据库的总体信息控制。
2.数据库体系的体系结构:

数据库体系是数据密集型应用的焦点,其体系结构受数据库运行所在的盘算机体系的影响很大,尤其是受盘算机体系结构中的连网、并行和分布的影响。从不同的角度或不同层次上看数据库体系体系结构不同;从终极用户的角度看,数据库体系体系结构分为集中式)分布式C/S(客户端/服务器)和并行结构。
1.集中式数据库体系:

在这种体系中,不仅数据是集中的,数据的管理也是集中的,数据库体系的全部功能(从情势的用户接口到DBMS 焦点)都集中在 DBMS 所在的盘算机上,如下图所示。大多数关系 DBMS 的产品也是从这种体系结构开始发展的,现在这种体系还在利用。
https://i-blog.csdnimg.cn/blog_migrate/d5929f20008ba59162e9265231a761cd.jpeg
2.客户端/服务器结构(C/S):

这种结构非常重要,它就是体现数据库在前后端中作用最好的实例。
许多现代软件都采用客户端/服务器体系结构,如下图所示。在这种结构中,一个处理机(客户端)的哀求被送到另一个处理机(服务器)上执行。其主要特点是客户端与服务器 CPU之间的职责明确,客户端主要负责数据表示服务,服务器主要负责数据库服务。采用客户端/服务器结构后,数据库体系功能分为前端和后端。前端主要包括图形用户界面、表格天生和报表处理等工具;后端负责存取结构、查询盘算和优化、并发控制以及故障规复等。前端与后端通过SQL或应用程序来接口。
https://i-blog.csdnimg.cn/blog_migrate/9ec65731c06cbf65f899bbaf25e5ed6b.jpeg
3.并行数据库体系:

并行体系结构的数据库体系是多个物理上连在一起的 CPU)而分布式体系是多个地理上分开的 CPÙ。
4.分布式数据库体系:

分布式 DBMS包括物理上分布,逻辑上集中的分布式数据库结构和物理上分布、逻辑上布的分布式数据库结构两种。
上述主要从介绍了数据库体系的角度来介绍了数据库在实际开发中的职位。
二、数据库在Django中的实际应用:

以Mysql为实例:
1、ORM:

ORM 是 django 提供的内置框架,是和一些关系型数据库的连接接口,利用类对象的方式操作数据(增删改查)。ORM 将类对象的操作语句转换为 SQL 语句,接着进入到数据库中获取效果,最后将效果转为对象的格式返回。
模型是项目的数据来源,模型类映射到数据库中的表,模型类中的每一个属性相当于表中的字段。
在 Django 中配置 MySQL 数据库 , 先在 MySQL 中创建好数据库(空)【一个数据库只能连接一个项目】。
在数据库自己已经创建好的Django文件中找到setting.py文件,找到DATABASE:
DATABASES = {
    'default': {
      'ENGINE': 'django.db.backends.mysql',#配置数据库引擎
      'HOST':'127.0.0.1',#主机
      'USER':'root',#数据库没创建前一般叫root(用户名)
      'PASSWORD':'',#自己数据库的密码
      #配置连接对数据库,数据库在连接前必须被创建好
      'NAME':'orm_13',#自己数据库的名字
    }
} 2、模型类:

关于模型类主要包括三大操作:
定义模型类 、数据迁移 、通过类对象进行操作数据。
1.定义模型类:

定义模型类 , 模型类都必须继承 Model 类。模型类定义在应用中的 models 文件。
from django.db import models

class Student(models.Model):
    # 定义属性,数据表中的字段
    # name char(10)
    # CharField 定义字符串字段,这个类型字段必须定义最大长度
    # max_length 定义字段的最大长度
    name = models.CharField(max_length=10)
    # age int()
    # IntegerField 定义整型字段
    age = models.IntegerField()
    # height float/double(3 , 2)
    # DecimalField 定义浮点类型
    # max_digits 浮点型的数据长度
    # decimal_places 浮点型小数位数
    height = models.DecimalField(max_digits=3, decimal_places=2)
    # gender enum('男','女')
    # 设置选择字段的选项值
    gender_choices = (
      #(选项字符 , 选项内容)
      ('1' , '女'),
      ('2' , '男'),
    )
    gender = models.CharField(choices=gender_choices , max_length=1) 上述代码主要介绍的就是定义模型类的方法,此中关于整形、浮点型大概字符型是啥,大概其它范例怎么表示,我在下面列一个表:
字段范例:
字段范例说明AutoField自动增量,32位整数。取值:1 ~ (2^31)-1BigAutoField自动增量,64位整数。取值:1 ~ (2^63)-1BigIntegerField64位整数。取值:-2^63 ~ (2^63)-1。字段默认表单控件为TextInputBinaryField存储原始的二进制数据BooleanField存储True大概False,字段默认表单控件为CheckboxInputCharField存储字符串。字段默认表单控件为TextInputDateField存储日期,字段值为datetime.date实例。字段默认表单控件为TextInput;参数auto_now表示每次生存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是利用当前日期,默以为False;参数auto_now_add表示当对象第一次 被创建时自动设置当前时间,用于创建的时间戳,它总利用当前日期,默以为False;参数auto_now_add和auto_now是相互排斥的, 组合将会发生错误.DateTimeField存储日期时间,字段值为datetime.datetime实例。字段默认表单控件为TextInputDecimalField存储固定精度的十进制数字段,字段值为Decimal实例。字段默认表单控件为NumberInput;参数max__digits表示总位数,参数decimal__places表示小数位数DurationField存储时间段EmailField存储E-mail地址FileField存储文件,字段默认表单控件为ClearableFileInputFilePathField存储文件路径FloatField存储浮点数。字段默认表单控件为NumberInputImageField存储图片。字段默认表单控件为ClearableFileInputIntegerField存储整数。取值:-2^31 ~ (2^31)-1GenericIPAdderssField存储字符串格式的IPv4大概IPv6地址。字段默认表单控件为TextInputPositiveIntegerField存储非负整数,取值:0~ (2^31)-1PositiveSmallIntegerField存储非负小整数。取值:0~ (2^15)-1SmallIntegerField存储小整数 , 取值范围-2^15 ~ (2^15)-1TextField存储大量文本。字段默认表单控件为TextareaTimeField存储时间。字段值为datetime.time实例 ,字段默认表单控件为TextInputURLField存储URL。字段默认表单控件为TextInputSlugField存储Slug数据 , 只包含字母、数字 、下换线或连字符 而其它细节在代码中的解释中都有提及。
2.数据迁移:

定义好模型类之后,必须进行数据迁移,数据库中才气同步到对应的数据表。
数据迁移要在项目的终端操作,在 manage.py 的同级目次下操作。
https://i-blog.csdnimg.cn/blog_migrate/267517245324d1e30a57c049c703e019.png然后输入:
python manage.py makemigrations 3.数据同步:

执行 migrate 命令 ,将模型类同步到数据库中。
同上在上述操作后继承在终端输入:
python manage.py migrate 4.注意:

1.在定义模型类的时候没有给其定义数据表的表名,在迁移同步到数据库中之后,这个表的表名会默认设置为:应用名_模型类名。
2.只要操作到 models.py 文件中的内容,就必须执行数据迁移和数据同步两个操作。
迁移过了之后增长字段,必须给新增的字段设置默认值,大概允许为空【null 设置是否允许为空(True/False),default 设置默认值】
ORM 在执行迁移数据的时候,会自动天生一个为主键且自增的id字段。
同时应该设置在数据库中的表名:(注意它是同属于模型类之下的)
class Meta:
      # 设置在数据库中的表名
      db_table = 'student'#以student为例子 假如发生迁移报错的问题如何解决,我在上一篇博客中已经做了具体介绍,有爱好的可以点击它直达:Pycharm中利用mysqlclient(Django)-CSDN博客。
3、数据操作:

1、利用 raw 方法操作原始 SQL:

from OrmApp1.models import Student

# 增加数据
sql = "insert into student(name , age , height , gender , weight)values" \
"('陈一' , 18 , 1.65 , '2' , 98.2),('刘二' , 19 , 1.75 , '2' , 178.2)"

# 将 sql 语句交给 raw 方法执行
# 通过模型类对象的方式进行操作
add_data = Student.objects.raw(sql)
# 对这个操作的返回值对象进行提交(增删改)
add_data.query._execute_query()

# 修改数据
sql = "update student set age=20 where id=2"
update_data = Student.objects.raw(sql)
update_data.query._execute_query()

# 删除数据
sql = 'delete from student where id=1'
delete_data = Student.objects.raw(sql)
delete_data.query._execute_query()

# 查询数据
sql = "select * from student"
# RawQuerySet 数据查询集,是一个对象
data = Student.objects.raw(sql)
print(data)
# 获取对象中的某个数据,需要使用循环
for i in data:
    # 获取到选项字段的具体数据:对象.get_字段名_display()
    print(i.name , i.age , i.get_gender_display()) 上述代码中就是用raw方法来操作增删改查SQL数据 ,具体细节在代码的解释中。
2、直接执行原始的 SQL 语句:

与pymysql操作类似:
from django.db import connection
# 创建游标
cursor = connection.cursor()
sql = "insert into student(name , age , height , gender , weight)values" \
"('陈一' , 18 , 1.65 , '2' , 98.2)"
cursor.execute(sql)

sql = "select * from student"
cursor.execute(sql)
data = cursor.fetchall()
print(data) 3、利用 django 提供的模型方法:

# 添加数据
# 方式一:会有返回值,是一个数据对象
add_data= Student.objects.create(name='张三' , age=25 , height=1.55 , gender='1' , weight=102.3)
print(add_data)
# 方式二:这种方式添加数据必须执行保存的方法
data = Student(name='李四' , age=35 , height=1.85 , gender='2' , weight=162.3)
data.save()

# 查询数据
# all 查询表中的所有数据
data = Student.objects.all()
# QuerySet 返回一个查询集对象
print(data)
for d in data:
    print(d.name, d.age, d.get_gender_display())

print('='*20)

# filter 相当于 where 子句
data = Student.objects.filter(gender='2')
for d in data:
    print(d.name, d.age, d.get_gender_display())
4、字段选项(总结):

选项说明Null默以为False。为True时,Django在字段没有数据时将空值NULL存储数据库(字符串字段存储空字符串)blank默以为False。为True时,字段允许为空,即表单验证允许输入空值。blank影响数据验证,null影响数据库数据存储choices为字段定义选择项。字段值为选项中的列表大概元组的值db_column定义字段在数据库表中的列名称,为设置时,Django用模型中的字段名作为数据库表的列名称db_index为True时,为该字段创建数据库索引db_tablespace若为字段创建了索引,则为字段索引设置数据库的表空间名称default设置字段默认值editable默认是True。为False时,字段不在模型表单中显示error_messages设置错误提示信息。该设置会覆盖默认的错误提示信息help_text设置字段的资助信息primary_key设置为True时,字段成为模型的主键unique设置为True时,字段值在整个表中必须是唯一的unique_for_date设置日期大概日期时间字段名,关联的两个字段值在整个表中必须是唯一的unique_for_month类似unique_for_date。与关联的月份唯一unique_for_year类似unique_for_date。与关联的年份唯一verbose_name为字段设置备注名称validators为字段设置校验器 5、字段查找范例(总结):

查找范例说明exact完全符合。例如:question_exact='text' 等同于where question='text'iexact与exact类似,但不区分字母大小写contains包含,区分字母大小写。例如question_contains = 'text' 等同于 where question like '%text%'icontains包含,不区分字母大小写in在指定项中进行匹配。例如id_in = 等同于 where id in(3,5),表达式可以是列表、元组、字符串、也可以是filter()、exclude()和get()等方法返回的包含当个字段值的查询集(QuerySet)gt大于。例如id_gt = 3 等同于 where id >3gte大于等于。例如id_gte = 3 等同于 where id >=3lt小于。例如id_lt = 3 等同于 where id <3lte小于等于。例如id_lte = 3 等同于 where id <=3startswith匹配字符串开头,区分大小写。例如question_startswith = 'text' 等同于 where question like 'text%'istartswith匹配字符串开头,不区分大小写。例如question_istartswith = 'text'endswith匹配字符串结尾,区分大小写。例如question_endswith = 'text' 等同于 where question like '%text'iendswith匹配字符串结尾,不区分大小写。例如question_iendswith = 'text'range范围测试。例如id_range(1 , 5) 等同于 where id between 1 and 5date查找datetime字段。例如rgDate_date = datetime.date(2023,5,31),可以和其他字段查找范例结合利用。例如rgDate_date_gt = datetime.date(2023,5,31)time查找datetime字段。例如rgDate_data = datetime.time(10,30),可以和其他字段查找范例结合利用。例如rgDate_data_gt = datetime.time(10,30)isnull取值True大概False,测试数据是否为NULL。例如:question_isnull = True 等同于 where question is NULLregex利用正则表达式进行匹配,区分大小写。例如,question_regex = "^*"iregex利用正则表达式进行匹配,不区分大小写。例如,question_iregex = "^*" 三、多表关系:

关于表与表之间的关系无非就为三种:一对一、一对多、多对多。
1、一对一关系:

表与表之间一对一这种关系最为焦点的头脑就是此中表的外键和别的一个表的主键之间创建一种联系。
具体操作:以下述代码为例子,创建一个people的表和idcard的表,此时在‘idcard’表中设立外键与‘people’表的主键创建联系。
具体细节具体见下述代码解释:
class People(models.Model):
    name = models.CharField(max_length=10)

    class Meta:
      db_table = 'people'

class IdCard(models.Model):
    ID_card = models.CharField(max_length=18)
    # 创建外键 , 建立和 People 表的一对一关系
    # OneToOneField: 一对一关系的字段
    # to : 设置关联的模型类名称
    # on_delete=models.CASCADE:设置级联删除 , 主表中删除数据从表有关联的数据也会被删除掉
    # 在模型类中创建的是属于外键对象
    # 设置关系之后会自动的关联对象表中的 id 字段 , 生成一个外键字段,外键字段的名称:外键对象名_id
    pel = models.OneToOneField(to='People' , on_delete=models.CASCADE)

    class Meta:
      db_table = 'idcard' 而此时创建好表之后要对表增长数据:
from OrmApp3.models import People , IdCard

# 主表数据:People
p1 = People.objects.create(name='谢bro')
p2 = People.objects.create(name='皓月当空')
p3 = People.objects.create(name='林谋')
p4 = People.objects.create(name='zero')
p5 = People.objects.create(name='车神')

# 从表数据:IdCard
# 使用外键字段添加关系
c = IdCard.objects.create(ID_card='20240322' , pel_id=1)
c = IdCard.objects.create(ID_card='20240323' , pel_id=3)
c = IdCard.objects.create(ID_card='20240324' , pel_id=4)

# 使用外键对象添加关联数据
# 获取 People 表中的数据对象
p = People.objects.get(id=2)
# 外键对象的值必须是一个对象类型的数据
c = IdCard.objects.create(ID_card='20250322' , pel=p) 更改数据:
# 更改关系
# 先获取要关联的主表中的数据对象
p = People.objects.get(id=5)
# 获取从表中要更改关系的数据对象
c = IdCard.objects.get(id=3)
#通过外键对象,修改外键对象值
c.pel_id = p
c.save() 删除数据:
# 删除数据
p = People.objects.get(id=2).delete()
# (2, {'OrmApp3.IdCard': 1, 'OrmApp3.People': 1})
print(p) 2、一对多关系:

一对多关系同样也是在表与表主键和外键之间创建一种能够多对一的关系。
class BJ(models.Model):
    name = models.CharField(max_length=10)
    class Meta:
      db_table = 'bj'

class Students(models.Model):
    stu_name = models.CharField(max_length=10)
    # ForeignKey 创建一对多的关系
    # related_name 设置反向数据操作 , 主表要操作从表的数据直接使用这个值,
    # 如果没有设置 就要使用 , 小写的模型类名称_set
    bj = models.ForeignKey(to='BJ' , on_delete=models.CASCADE , related_name='sub')
    class Meta:
      db_table = 'students' 3、多对多关系:

多对多关系同样也是在表与表主键和外键之间创建一种能够多对多的关系,例如学生与所学科目之间的关系就是这种多对多关系。
class Shet(models.Model):
    name = models.CharField(max_length=10)
    class Meta:
      db_table = 'shet'
class Stus(models.Model):
    stu_name = models.CharField(max_length=10)
    # ManyToManyField: 创建多对多的外键对象
    # 数据迁移同步之后,在数据库中会自动的创建一个外键关系表,表名:模型类名称_外键对象名
    sh = models.ManyToManyField(to='Shet')
    class Meta:
      db_table = 'stus' 四、分页器:

数据分页 , 利用 Paginator 类实现数据分页。
from django.core.paginator import Paginator

    # Paginator(可迭代对象 , 每一页允许出现的最大数据条数)
    ls =
    # 制作分页器
    p = Paginator(ls , 4)

    # 查询数据分页的总页数
    print(p.num_pages)
    # 获取到数据的总条数
    print(p.count)
    # 获取到每一页的迭代对象
    print(p.page_range)

    # 获取分页器对象中的某一页内容对象
    page = p.page(3)
    # 获取到页面的数据
    print(page.object_list)
    # 查询当前对象的页数
    print(page.number)
    # 判断是否有上一页
    print(page.has_previous())
    # 判断是否有下一页
    print(page.has_next())
    # 获取上一页的页码
    print(page.previous_page_number())
    # 获取下一页的页码
    print(page.next_page_number()) 五.总结:

该篇博客先介绍了数据库及其在开发中的职位,然后介绍了数据库在Django中的实际应用(ORM、模型类、数据操作、字段选项的总结、字段查找范例的总结),其次介绍了三种表的关系(一对一、一对多、多对多),最后介绍了分页器。如若各位大佬发现问题大概需要补充的地方,欢迎指正,后续我还会继承更新关于Django的其它内容,欢迎各人关注我等后续更新。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Django之数据库篇(Python)