当前位置: 首页 > news >正文

(万字长文)Django数据库操作——ORM:数据交互显示前端网页

🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!

亲爱的读者,

感谢你花时间阅读这篇分享。希望这里的每一个字都能为你带来启发或是让你会心一笑。如果你觉得这篇文章有价值,或者它解决了你一直以来的一个疑问,请给个赞吧 —— 这不仅是对我学习效果的认可,更是激励我继续前行的动力!

而且,如果你不想错过未来更多有趣的内容,记得点击关注哦!这样,每当有新文章发布时,你就能第一时间收到通知啦。让我们一起在这个充满无限可能的知识海洋中遨游,探索未知的世界吧!

最后,别忘了留下你的想法或问题在评论区。无论是赞美、建议还是疑问,我都非常期待听到你的声音。也许,正是你的那条评论,将开启一段全新的讨论旅程呢!

🌟 点赞、关注、留言 —— 三连走起,让我们共同成长,一起变得更优秀!

再次感谢每一位可爱的你,愿你在追求梦想的路上一帆风顺!

接续上篇文章:Django的请求和响应+template模板-CSDN博客

目录

🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!

4.4.8 orm——连接Mysql数据库

1.Django开发操作数据库更为简单:orm

2.安装第三方模块

3.创建数据库

4.连接MySql的配置

5.Django操作表

6.操作表中的数据(增、删、改、查)

一、增加数据

二、删除数据

三、修改数据

四、查询数据

如何在Django中使用ORM进行数据的批量插入?

7.用户管理(案例):


4.4.8 orm——连接Mysql数据库
1.Django开发操作数据库更为简单:orm

orm本身是不能连接数据库的,也需要通过工具:pymsql、MySqldb

orm扮演角色:翻译官(代码翻译成为相应的MySql数据)

2.安装第三方模块
pip install mysqlclient

如果安装不了:就采用whl包的方式

下载链接:mysqlclient · PyPI

3.创建数据库

ORM作用:数据库需要自己创建

  1. 操作(创建、修改、删除)数据库表

  2. 操作表中的数据:(不用写sql语句)

    使用工具:NAvicat可视化创建数据库

4.连接MySql的配置

修改项目 settings.py

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql',  # 使用 MySQL 引擎'NAME': 'django_project',              # 数据库名(需提前创建)'USER': 'username',                    # 数据库用户名'PASSWORD': 'password',                # 数据库密码'HOST': 'localhost',                   # 数据库主机(默认本地)'PORT': '3306',                        # 端口(默认 3306)'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",  # 严格模式(可选)'charset': 'utf8mb4'                                 # 字符集(推荐 utf8mb4)}}
}

注意事项

  • 使用 pymysql 替代 mysqlclient

    (若 mysqlclient 安装失败):

    1. 安装 pymysql:

      pip install pymysql
    2. 在项目同名目录(与settings.py同级)的init.py中添加:

      import pymysql
      pymysql.install_as_MySQLdb()

最后操作效果:

  1. auth_group

  • 用途:存储用户组信息。

  • 字段示例:

    • id:组的唯一标识符。

    • name:组的名称。

  1. auth_group_permissions

  • 用途:关联用户组与权限的关系。

  • 字段示例:

    • id:关系记录的唯一标识符。

    • group_id:所属用户组的 ID。

    • permission_id:关联的权限 ID。

  1. auth_permission

  • 用途:存储系统中的所有权限信息。

  • 字段示例:

    • id:权限的唯一标识符。

    • name:权限的名称。

    • content_type_id:关联的内容类型 ID(即哪个模型拥有该权限)。

    • codename:权限的代码名称,用于程序中引用。

  1. auth_user

  • 用途:存储用户的基本信息。

  • 字段示例:

    • id:用户的唯一标识符。

    • username:用户名。

    • password:加密后的密码。

    • email:邮箱地址。

    • is_staffis_superuser:是否为管理员或超级用户。

    • date_joined:注册日期。

  1. auth_user_groups

  • 用途:关联用户与用户组的关系。

  • 字段示例:

    • id:关系记录的唯一标识符。

    • user_id:所属用户的 ID。

    • group_id:关联的用户组 ID。

  1. auth_user_user_permissions

  • 用途:关联用户与权限的关系。

  • 字段示例:

    • id:关系记录的唯一标识符。

    • user_id:所属用户的 ID。

    • permission_id:关联的权限 ID。

  1. django_admin_log

  • 用途:记录后台管理系统的操作日志。

  • 字段示例:

    • id:日志记录的唯一标识符。

    • action_time:操作时间。

    • user_id:执行操作的用户 ID。

    • content_type_id:被操作对象的内容类型 ID。

    • object_id:被操作对象的 ID。

    • object_repr:被操作对象的表示字符串。

    • action_flag:操作类型(如添加、修改、删除)。

    • change_message:变更描述。

  1. django_content_type

  • 用途:存储应用中所有模型的内容类型信息。

  • 字段示例:

    • id:内容类型的唯一标识符。

    • app_label:所属应用的标签。

    • model:模型名称。

  1. django_migrations

  • 用途:记录数据库迁移的历史。

  • 字段示例:

    • id:迁移记录的唯一标识符。

    • app:迁移的应用名称。

    • name:迁移文件的名称。

    • applied:迁移应用的时间。

  1. django_session

  • 用途:存储用户的会话信息。

  • 字段示例:

    • session_key:会话键。

    • session_data:会话数据(通常为序列化后的字典)。

    • expire_date:会话过期时间。

5.Django操作表

创建表:

from django.db import models
​
class UserInfo(models.Model):name = models.CharField(max_length=32)password = models.CharField(max_length=64)age = models.IntegerField()

执行命令:

 python manage.py makemigrationspython manage.py migrate  

注意:app必须是要已经注册了的

上图中,之所以会有其他的表,是因为Django内置了的,如下图:

一旦不想使用有些表,就直接注释掉即可。

创建和修改表结构:

直接在models.py文件里面添加class结构。

如果在原有创建表的基础上进行添加新的字段:

size = models.IntegerField()

那么就会如图所示,进行选择。

1)→代表的就是让你一个一个去填写对应字段值

2)→代表的就是退出如果在 models.IntegerField()的括号中加入default=3值,那么就是默认键值

3)允许为空:

data = models.IntegerField(null = True,blank=true)

所以以后在开发过程中:想要修改表中的“字段”

通过修改app下的models.py文件中的class中的代码进行注释即可,然后在进行以下命令:

python manage.py makemigrations
​
python manage.py migrate      
6.操作表中的数据(增、删、改、查)

在 Django 中,通过 ORM(对象关系映射)可以方便地对数据库表中的数据进行增、删、改、查操作。前面我们已经定义了几个模型类,如下所示:

from django.db import models
​
# 用户信息模型类
class UserInfo(models.Model):name = models.CharField(max_length=32)password = models.CharField(max_length=64)age = models.IntegerField()
​
# 部门模型类
class Department(models.Model):title = models.CharField(max_length=16)
​
# 角色模型类
class Role(models.Model):caption = models.CharField(max_length=16)
一、增加数据
  1. 使用create方法 通过模型类.objects.create(字段=值)的方式可以快速创建一条数据记录。例如前面已经使用过的创建部门数据。

Department.objects.create(title = "销售部")

这会在Department表中插入一条title为 “销售部” 的记录。

如果要创建UserInfo表的数据,可以这样写:

UserInfo.objects.create(name="张三", password="123456", age=25)

上述代码会在UserInfo表中插入一条用户名为 “张三”,密码为 “123456”,年龄为 25 岁的记录。

  1. 先实例化再保存 也可以先实例化一个模型对象,然后调用其save方法来保存到数据库。比如创建Role表的数据:

role_obj = Role(caption="管理员")
role_obj.save()

这种方式在需要对对象进行一些额外处理后再保存时比较有用,例如给对象的某些属性动态赋值等。

二、删除数据
  1. 使用delete方法 对于已经获取到的模型对象实例,可以调用其delete方法来删除对应的数据记录。假设我们已经获取到了一个UserInfo对象:

user = UserInfo.objects.get(name="张三")  # 先获取到名为“张三”的用户对象
user.delete()  # 删除该用户记录

也可以通过查询集批量删除数据。比如删除所有年龄小于 20 岁的用户:

UserInfo.objects.filter(age__lt=20).delete()

这里filter方法筛选出符合条件(年龄小于 20 岁)的查询集,然后调用delete方法将这些记录全部删除。

三、修改数据
  1. 先获取对象再修改属性并保存 先从数据库中获取到要修改的模型对象,然后修改其属性值,最后调用save方法保存修改。例如修改 “销售部” 部门名称为 “市场销售部”:

department = Department.objects.get(title="销售部")
department.title = "市场销售部"
department.save()
  1. 使用update方法批量修改 如果要批量修改满足一定条件的数据,可以使用update方法。比如将所有用户的年龄都增加 1 岁:

UserInfo.objects.all().update(age=models.F('age') + 1)

这里models.F对象用于在不获取具体值的情况下对字段进行操作,实现直接在数据库层面的计算更新。

四、查询数据

使用get方法获取单个对象 get方法用于获取满足特定条件的单个对象。例如获取名为 “张三” 的用户:

user = UserInfo.objects.get(name="张三")

注意,如果查询结果不存在或者存在多条满足条件的记录,get方法会抛出异常(DoesNotExistMultipleObjectsReturned)。

使用filter方法获取查询集 filter方法用于获取满足条件的多个对象,返回的是一个查询集。例如获取所有年龄大于 30 岁的用户:

users = UserInfo.objects.filter(age__gt=30)
for user in users:print(user.name, user.age)

这里age__gt=30表示筛选条件为年龄大于 30 岁,__gt是 Django ORM 中的查询运算符,表示 “大于”。类似的还有__lt(小于)、__gte(大于等于)、__lte(小于等于)等。

使用all方法获取所有对象 all方法用于获取模型表中的所有记录,返回查询集。例如获取所有部门:

departments = Department.objects.all()
for department in departments:print(department.title)

使用exclude方法排除某些对象 exclude方法用于排除满足特定条件的对象,返回剩余的查询集。例如获取除了 “管理员” 角色之外的其他角色:

roles = Role.objects.exclude(caption="管理员")
for role in roles:print(role.caption)

通过以上这些增、删、改、查操作,我们可以灵活地管理数据库表中的数据,充分发挥 Django ORM 的便捷性和强大功能。

如何在Django中使用ORM进行数据的批量插入?

在 Django 中使用 ORM 进行数据的批量插入,通常使用bulk_create方法,以下是详细步骤:

1. 定义模型

首先要定义 Django 模型类,它对应数据库中的表结构。例如,定义一个存储书籍信息的模型:

from django.db import models
​
class Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=50)publish_year = models.IntegerField()

2. 准备数据

准备要批量插入的数据,一般以列表形式呈现,列表中的每个元素是一个字典,字典的键对应模型字段名,值为要插入的数据。例如:

books_data = [{"title": "Python基础教程","author": "张三","publish_year": 2020},{"title": "Django实战指南","author": "李四","publish_year": 2022},{"title": "Web开发入门","author": "王五","publish_year": 2021}
]

3. 执行批量插入

使用bulk_create方法进行数据插入。先将准备好的数据转换为模型实例,再调用该方法:

# 创建模型实例
book_instances = [Book(title=book["title"], author=book["author"], publish_year=book["publish_year"]) for book in books_data]
# 执行批量插入
Book.objects.bulk_create(book_instances)

也可以更简洁地写成:

Book.objects.bulk_create([Book(title=book["title"], author=book["author"], publish_year=book["publish_year"]) for book in books_data])

4. 验证插入结果

可以通过查询数据库来验证数据是否成功插入:

all_books = Book.objects.all()
for book in all_books:print(book.title, book.author, book.publish_year)

注意事项

  • 事务处理bulk_create默认在单个事务中执行,这意味着要么所有数据都插入成功,要么都失败回滚,适用于不需要逐条验证的场景 。

  • 信号发送bulk_create不会发送 Django 的post_save信号,如果业务逻辑依赖此信号,需要手动处理。

  • 性能考量:当数据量非常大时,可以通过设置batch_size参数分批次插入,以避免占用过多内存。例如:

batch_size = 100
for i in range(0, len(book_instances), batch_size):batch = book_instances[i:i + batch_size]Book.objects.bulk_create(batch)

bulk_create相比逐条插入(如使用循环调用save方法),能显著减少数据库交互次数,提升插入效率,尤其适合处理大量数据的场景。

7.用户管理(案例):
views.py:
​
def user_list(request):"""用户列表页"""users = User.objects.all()return render(request, 'user_list.html', {'users': users})
​
def user_add(request):"""添加用户"""if request.method == 'POST':form = UserForm(request.POST)if form.is_valid():form.save()messages.success(request, '用户添加成功!')return redirect('user_list')else:form = UserForm()return render(request, 'user_add.html', {'form': form})
​
def user_edit(request, pk):"""编辑用户"""user = get_object_or_404(User, pk=pk)if request.method == 'POST':form = UserForm(request.POST, instance=user)if form.is_valid():form.save()messages.success(request, '用户更新成功!')return redirect('user_list')else:form = UserForm(instance=user)return render(request, 'user_edit.html', {'form': form, 'user': user})
​
def user_delete(request, pk):"""删除用户"""user = get_object_or_404(User, pk=pk)if request.method == 'POST':user.delete()messages.success(request, '用户删除成功!')return redirect('user_list')return render(request, 'user_confirm_delete.html', {'user': user})
​

urls.py:path("user/user_list", user_list, name="user_list"),path("user/user_add", user_add, name="user_add"),path("user/user_edit/<int:pk>/", user_edit, name="user_edit"),path("user/user_delete/<int:pk>/", user_delete, name="user_delete"),

base.url:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>用户管理系统</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body><div class="container mt-5">{% if messages %}{% for message in messages %}<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">{{ message }}<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>{% endfor %}{% endif %}{% block content %}{% endblock %}</div><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

user_list.html:
{% extends 'base.html' %}
​
{% block content %}
<div class="card"><div class="card-header"><h3 class="card-title">用户列表</h3><!-- 去掉 'users:' 前缀 --><a href="{% url 'user_add'%}" class="btn btn-primary float-end">添加用户</a></div><div class="card-body"><table class="table table-striped table-hover"><thead><tr><th>ID</th><th>用户名</th><th>邮箱</th><th>性别</th><th>年龄</th><th>状态</th><th>创建时间</th><th>操作</th></tr></thead><tbody>{% for user in users %}<tr><td>{{ user.id }}</td><td>{{ user.username }}</td><td>{{ user.email }}</td><td>{{ user.get_gender_display }}</td><td>{{ user.age|default:"-" }}</td><td>{% if user.is_active %}<span class="badge bg-success">激活</span>{% else %}<span class="badge bg-danger">禁用</span>{% endif %}</td><td>{{ user.created_at|date:"Y-m-d H:i" }}</td><td><!-- 去掉 'users:' 前缀 --><a href="{% url 'user_edit' user.pk %}" class="btn btn-sm btn-warning">编辑</a><a href="{% url 'user_delete' user.pk %}" class="btn btn-sm btn-danger">删除</a></td></tr>{% endfor %}</tbody></table></div>
</div>
{% endblock %}

user_add.html:
{% extends 'base.html' %}
​
{% block content %}
<div class="card"><div class="card-header"><h3 class="card-title">添加用户</h3></div><div class="card-body"><form method="post">{% csrf_token %}{{ form.as_p }}<button type="submit" class="btn btn-primary">保存</button><a href="{% url 'user_list' %}" class="btn btn-secondary">取消</a></form></div>
</div>
{% endblock %}

user_confirm_delete.html:
{% extends 'base.html' %}
​
{% block content %}
<div class="card"><div class="card-header"><h3 class="card-title">确认删除</h3></div><div class="card-body"><p>你确定要删除用户 "{{ user.username }}" 吗?</p><form method="post">{% csrf_token %}<button type="submit" class="btn btn-danger">确认删除</button><a href="{% url 'user_list' %}" class="btn btn-secondary">取消</a></form></div>
</div>
{% endblock %}

user_edit.html:
{% extends 'base.html' %}
​
{% block content %}
<div class="card"><div class="card-header"><h3 class="card-title">编辑用户: {{ user.username }}</h3></div><div class="card-body"><form method="post">{% csrf_token %}{{ form.as_p }}<button type="submit" class="btn btn-primary">保存</button><a href="{% url 'user_list' %}" class="btn btn-secondary">取消</a></form></div>
</div>
{% endblock %}

效果图:

相关文章:

  • OPC Client第5讲(wxwidgets):初始界面的事件处理;按照配置文件初始化界面的内容
  • 07_分类器不确定评估
  • 「短剧系统开发」定制化技术架构|高并发微服务 + AI 推荐,快速搭建流量级短剧平台
  • JMeter-SSE响应数据自动化
  • SpringBoot-10-SpringBoot结合MyBatis操作mysql并提供web服务
  • 李宏毅《深度学习》:Self-attention 自注意力机制
  • [Datagear] 实现按月颗粒度选择日期的方案
  • 目前,Navicat 17.1 版本的用户管理功能无法使用,如何回退到上一个版本?关于之前提到的转置功能?
  • WebSphere Application Server(WAS)8.5.5教程第十二讲:EJB
  • 【Qt开发】Qt核心属性
  • 线程封装与互斥
  • OpenCV CUDA 模块图像过滤------创建一个线性滤波器(Linear Filter)函数createLinearFilter()
  • 使用 FFmpeg 将视频转换为高质量 GIF(保留原始尺寸和帧率)
  • ROS2学习(9)------ROS2动作
  • 【算法篇】二分查找算法:基础篇
  • java中string类型的list集合放到redis的5种数据类型的那种比较合适呢,可以用StringRedisTemplate实现
  • 现代软件开发利器
  • JavaScript对象继承
  • Git 分支管理:merge、rebase、cherry-pick 的用法与规范
  • 鸿蒙进阶——Framework之Want 隐式匹配机制概述
  • 沈阳网站建设费用/seo案例
  • 网站建设合同 完整版/东莞网站建设市场
  • asp.net个人网站怎么做/微信销售平台
  • 微信朋友圈做网站推广赚钱吗/百度一下你就知道下载
  • 原创 网站 源码/优化网站怎么做
  • 建站系统的选用分析/广点通广告平台