Django模型:数据库操作全指南

文章目录

一、数据库的基本概念

模型(数据库)

基本概念:Django模型是Django框架中用于定义数据结构的核心组件。每个模型对应数据库中的一张表,模型的属性对应表的字段。通过模型,开发者可以用Python代码操作数据库,无需直接编写SQL语句
定义方式:在Django应用的models.py文件中定义模型类,继承自django.db.models.Model。每个类属性代表一个数据库字段,字段类型由Django的字段类决定

常用字段类型 含义
AutoField 自动增长的IntegerField(不指定时Django会自动创建属性名为id的自动增长属性)
CharField 字符串(max_length表示最大字符个数)
TextField 大文本字段(一般超过4000个字符时使用)
IntegerField 整数
FloatField 浮点数
DecimalField 十进制浮点数(参数max_digits表示总位数,参数decimal_places表示小数位数)
BooleanField 布尔值(True、False)
NullBooleanField 支持Null、True、False三种值
DateField 日期,参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间截,它总是使用当前日期,默认为False; 参数auto now add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False: 参数auto now add和auto now是相互排斥的,组合将会发生错误
TimeField 时间,参数同DateField
DateTimeField 日期时间,参数同DateField
FileField 上传文件字段
lmageField 继承于FileField,对上传的内容进行校验,确保是有效的图片
ForeignKey 定义多对一关系
ManyToManyField 定义多对多关系
OneToOneField 定义一对一关系
选项 说明
null 是否为空
unique 唯一
default 设置默认值
varbose_name 主要是admin后台显示名字

外键 :在设置外键时,需要通过 on_delete 选项指明主表除数据时,对于外键引用表数据如何处理

on_delete 参数 含义
on_delete=None 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE 级联(删除主表数据时连通一起删除外键表中数据)
on_delete=models.DO_NOTHING 删除关联数据,什么也不做
on_delete=models.PROTECT 保护(通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据)
on_delete=models.SET_NULL 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
on_delete=models.SET_DEFAULT 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET 删除关联数据(与之关联的值设置为指定值,设置:models.SET(值); 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象))

二、数据库的基本开发步骤

模型开发步骤 :

  1. 定义模型类(子应用的models.py
python 复制代码
from django.db import models


class BookInfo(models.Model):
    name = models.CharField(max_length=10, unique=True, verbose_name='名字')  # 唯一
    # 发布日期
    pub_data = models.DateField(null=True)
    # 阅读量
    readcount = models.IntegerField(default=0)
    # 评论量
    commentcount = models.IntegerField(default=0)
    # 是否逻辑删除
    is_delete = models.BooleanField(default=False)


    class Meta:
        # 改表名
        db_table = 'bookinfo'
        # 修改后台admin的显示信息的配置
        verbose_name = 'admin'

    def __str__(self):
        return self.name

class PeopleInfo(models.Model):
    name = models.CharField(max_length=10)
    gender = models.BooleanField()
    # 外键  表与表之间关联的时候,必须要写 on_delete 参数,否则会报异常
    book = models.ForeignKey(BookInfo, on_delete=models.CASCADE)
  1. model编写完后,执行指令生成迁移文件:python manage.py makemigrations(需 settings.py 提前关联配置,否则会失败)
  2. 执行指令实现迁移:python manage.py migrate(会在数据库中生成表)
    执行完成,在主应用的 settings.py 中可以查看使用的是什么数据库(根据下面文件,根目录下会生成 db.sqlite3 数据库文件)
python 复制代码
DATABASE = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

三、创建管理员账户管理数据库

自带登入功能

项目运行python manage.py runserver之后,浏览页面http://127.0.0.1:8000/admin会自动跳到登入页面

此时查询auto_user数据库是没有数据的,需要使用指令创建一个后台管理用户,python manage.py createsuperuser,运行指令后输入账号、邮箱、密码,执行指令后

再次查看auto_user数据库中有一条数据,然后通过浏览http://127.0.0.1:8000/admin页面,输入账号和密码可以登入,在这可以进行写数据相关操作

如果在数据库中没有展示具体内容,可能要在对应的models.py中添加__str__相关内容

python 复制代码
from django.db import models

class BookInfo(models.Model):
    name = models.CharField(max_length=10)

    def __str__(self):
        return self.name

在子应用的admin.py中添加如下内容

python 复制代码
from django.contrib import admin
from login.models import BookInfo

# Register your models here.
admin.site.register(BookInfo)

在子应用的apps.py类中可以添加变量verbose_name修改标题(verbose_name='后台相关'),修改后,settings.py中INSTALLED_APPS中要以login.apps.LoginConfig格式来,然后http://127.0.0.1:8000/admin对应数据库的模块标题就会变为指定的

四、数据库切换与配置

在主应用的__init__.py中输入如下内容

python 复制代码
import pymysql
pymysql.install_as_MySQLdb()

修改主应用的settings.py修改这段代码进行配置

python 复制代码
# 小型数据库:Sqlite
# 中型数据库:MySQL,Sqlserver
# 大型数据库:oracle,DB2
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1', # 主机
        'PORT': '3306',      # 端口
        'USER': 'root',      # 用户名
        'PASSWORD': 'mysql', # 密码
        'NAME': 'book',      # 指定数据库
    }
}

编写对应的models.py

然后运行:python manage.py makemigrations

现在数据库中还没有该数据库,再执行:python manage.py migrate

执行之后,数据库中就有对应数据表了
有了数据表之后,可以通过cmd链接数据库,对数据库进行操作,也可以在视图中对数据库操作

sql 复制代码
from django.shortcuts import render
from django.http import HttpResponse
from book.models import BookInfo

# Create your views here.

def index(request):
    # 到数据库中查询数据
    books = BookInfo.objects.all()
    # 组织数据
    context ={'books': books}
    # 传递给模板
    # render(request, '', context)

    return HttpResponse('index')

五、数据库操作

iPython(python manage.py shell)

终端执行

如果要手动执行sql指令,比如查询、插入数据,可以执行指令:python manage.py shell

然后执行下面代码from book.models import BookInfoBookInfo.objects.all()

接着就会显示数据库中查询到的内容
代码中执行(如 views.py 视图中)

python 复制代码
from book.models import BookInfo

def index(request):
    # 新增数据
    book = BookInfo(name='python', pub_data='2000-01-01')
    book.save()
    # ...

新增数据

sql 复制代码
from book.models import BookInfo

# 新增数据  方式一
book = BookInfo(name='python', pub_data='2000-01-01')
book.save()

# 新增数据  方式二(直接入库)
# object模型的管理类  对模型的增删改查都找它
BookInfo.objects.create(name='java', pub_data='2001-01-02')

修改更新数据

sql 复制代码
from book.models import BookInfo

# 方式一
book = BookInfo.objects.get(id=1)  # 查询数据  相当于select * from bookinfo where id=1
book.readcount=20   # 更新数据
book.save()         # 调用save保存
# 方式二
BookInfo.objects.filter(id=1).update(readcount = 100, commentcount = 200)

删除操作

sql 复制代码
from book.models import BookInfo

# 方式一
book = BookInfo.objects.get(id=5)  # 先获取数据
book.delete()   # 调用删除方法
# 方式二
BookInfo.objects.filter(id=4).delete()

查询操作

sql 复制代码
from book.models import BookInfo

# get得到某一个数据   不存在会抛出异常
try:
    book = BookInfo.objects.get(id=1)  # select * from bookinfo where id=1
    print(book.name, book.readcount)
except Exception:
    pass

# all 获取所有数据
book = BookInfo.objects.all()

# count 获取总个数
BookInfo.objects.count()

排序

sql 复制代码
from book.models import BookInfo

BookInfo.objects.all().order_by('readcount')   # 升序
BookInfo.objects.all().order_by('-readcount')  # 降序

过滤查询(filter、get、exclude)

filter、get、exclude都是相当于where查询,类似于 select * from bookinfo where id=1
filter :筛选/过滤 返回多个结果
get : 返回1个结果
exclude :排除掉符合条似剩下的结果,相当于not
新式语法,如filter(字段名__运算符=值)

运算符 含义
exact 等于 (get(id=1)等效于get(id__exact=1)
contains 包含
endswith 以什么结尾
isnull 为空
in in判断
gt 大于
gte 大于等于
lt 小于
lte 小于等于
sql 复制代码
from book.models import BookInfo

# 查询编号为1的图书
BookInfo.objects.get(id=1)  # 返回单一对象   等效于  id__exact=1
BookInfo.objects.filter(id__exact=1)   # 返回列表

# 查询书名含'笑'的图书
BookInfo.objects.filter(name__contains='笑')
# 查询书名以'部'结尾的图书
BookInfo.objects.filter(name__endswith='部')
# 查询书名为空的图书
BookInfo.objects.filter(name__isnull=True)
# 查询编号为1或3或5的图书
BookInfo.objects.filter(id__in=[1, 3, 5])
# 查询编号大于3的图书
BookInfo.objects.filter(id__gt=3)
# 查询数据id不为3的图书
BookInfo.objects.exclude(id=3)
# 查询1980年发表的图书
BookInfo.objects.filter(pub_data__year='1980')
# 查询1990年1月1日后发表的图书
BookInfo.objects.filter(pub_data__gt='1990-1-1')

# 多条件查询
BookInfo.objects.filter(id__gt=2).filter(readcount__gt=20)

字段间对比查询(F对象)

用于属性与属性之间的比较,F对象的语法形式

语法:filter(字段名__运算符=F('字段名'))

sql 复制代码
from book.models import BookInfo
from django.db.models import F

# 查询阅读量(readcount)大于等于评论量的图书(commentcount)
BookInfo.objects.filter(readcount__gt=F('commentcount'))
# 查询阅读量大于等于评论量两倍的图书
BookInfo.objects.filter(readcount__gt=F('commentcount')*2)

多条件查询(Q对象)

多条件查询,如:需要查询id大于2 并且阅读量大于20的书籍

语法:或: Q()|Q();与:Q()&Q(); 非:~Q()

sql 复制代码
from book.models import BookInfo
from django.db.models import Q

# 需要查询id大于2并且阅读量大于20的书籍
BookInfo.objects.filter(id__gt=2).filter(readcount__gt=20)  # 方式一
BookInfo.objects.filter(id__gt=2, readcount__gt=20)  # 方式二

# 方法三,使用Q对象
BookInfo.objects.filter(Q(id__gt=2)&Q(readcount__gt=20))

# 需要查询id大于2或者阅读量大于20的书籍,这时候需要用到Q对象
BookInfo.objects.filter(Q(id__gt=2)|Q(readcount__gt=20))

聚合函数(计算,累计)

聚合函数需要使用 aggregate方法

语法格式: aggregte(Xxx('字段'))

sql 复制代码
from book.models import BookInfo
from django.db.models import Sum,Avg,Max,Min,Count

# 当前数据的阅读总量
BookInfo.objects.aggregate(Sum('readcount'))

联表查询(多表)

比如书籍中没有任何关于人物的字段,人物中有关专书籍的字段 book 外键,书籍和人物的关系是 l:n
语法形式

通过书籍查询人物:主表模型.关联模型类名小写_set.all()

通过人物查询书籍:从表模型(实例对象).外键
通过书籍查询人物(一对多):查询书籍为1的所有人物信息

sql 复制代码
from book.models import BookInfo

# 查询书籍
book = BookInfo.objects.get(id=1)
# 根据书籍关联人物信息
book.peopleinfo_set.all()

通过人物查询书籍(多对一):查询人物为1的书籍信息

sql 复制代码
from book.models import PeopleInfo
# 查询人物
person = PeopleInfo.objects.get(id=1)
# 根据人物查询书籍
person.book.name

联表查询过滤(多表)

语法形式

一对多

需要的是图书信息,已知条件是人物信息filter(关联模型类名小写__字段__运算符=值)

需要的是主表数据,已知条件是从表信息filter(关联模型类名小写__字段__运算符=值)
多对一

需要的是人物信息,已知条件是书籍信息filter(外键__字段__运算符=值)

需要是是从表数据,已知条件是主表信息filter(外键__字段__运算符=值)

sql 复制代码
from book.models import BookInfo

# 一对多
# 查询图书,要求图书人物为郭靖
BookInfo.objects.filter(peopleinfo__name__exact='郭靖')
BookInfo.objects.filter(peopleinfo__name='郭靖')
# 查询图书,要求图书中人物的表述包含'八'
BookInfo.objects.filter(peopleinfo__description__contains='八')

# 多对一
# 查询书名为"天龙八部"的所有人物
PeopleInfo.objects.filter(book__name='天龙八部')
PeopleInfo.objects.filter(book__name_exact='天龙八部')
# 查询困书阅读量大于30的所有人物
PeopleInfo.objects.filter(book__readcount__gt=30)

数据分页

链接:https://docs.djangoproject.com/en/4.2/topics/pagination/

python 复制代码
from book.models import BookInfo
from django.core.paginator import Paginator

books = BookInfo.objects.all()
# 将数据分页
# object_list 结果集/列表
# per_page  每页多少记录
p = Paginator(books, 2)
# 获取第几页数据
books_page = p.page(1)
books_page[0]
相关推荐
六月雨滴1 小时前
Oracle 数据库网络安全之加密配置
数据库·web安全·oracle
2401_867623982 小时前
如何设置用户默认表空间_ALTER USER DEFAULT TABLESPACE
jvm·数据库·python
callJJ2 小时前
SQL 调优完全指南 —— 从入门到实战
数据库·sql·调优·慢查询
努力成为DBA的小王2 小时前
MySQL数据类型
数据库·mysql
日取其半万世不竭2 小时前
Supabase 自建:开源的 Firebase 替代品,带数据库的后端服务
数据库·开源
2301_803934612 小时前
html标签怎样划分页面区域_section与div的区别【介绍】
jvm·数据库·python
埃伊蟹黄面2 小时前
MySQL 库的操作
数据库·mysql
埃伊蟹黄面2 小时前
数据库基础认识
数据库
看我干嘛!2 小时前
Redis安装
数据库·redis·缓存