🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!
亲爱的读者,
感谢你花时间阅读这篇分享。希望这里的每一个字都能为你带来启发或是让你会心一笑。如果你觉得这篇文章有价值,或者它解决了你一直以来的一个疑问,请给个赞吧 —— 这不仅是对我学习效果的认可,更是激励我继续前行的动力!
而且,如果你不想错过未来更多有趣的内容,记得点击关注哦!这样,每当有新文章发布时,你就能第一时间收到通知啦。让我们一起在这个充满无限可能的知识海洋中遨游,探索未知的世界吧!
最后,别忘了留下你的想法或问题在评论区。无论是赞美、建议还是疑问,我都非常期待听到你的声音。也许,正是你的那条评论,将开启一段全新的讨论旅程呢!
🌟 点赞、关注、留言 —— 三连走起,让我们共同成长,一起变得更优秀!
再次感谢每一位可爱的你,愿你在追求梦想的路上一帆风顺!
接续上篇文章: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作用:数据库需要自己创建
-
操作(创建、修改、删除)数据库表
-
操作表中的数据:(不用写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 安装失败):
-
安装 pymysql:
pip install pymysql
-
在项目同名目录(与settings.py同级)的init.py中添加:
import pymysql pymysql.install_as_MySQLdb()
-
最后操作效果:
-
auth_group
-
用途:存储用户组信息。
-
字段示例:
-
id
:组的唯一标识符。 -
name
:组的名称。
-
-
auth_group_permissions
-
用途:关联用户组与权限的关系。
-
字段示例:
-
id
:关系记录的唯一标识符。 -
group_id
:所属用户组的 ID。 -
permission_id
:关联的权限 ID。
-
-
auth_permission
-
用途:存储系统中的所有权限信息。
-
字段示例:
-
id
:权限的唯一标识符。 -
name
:权限的名称。 -
content_type_id
:关联的内容类型 ID(即哪个模型拥有该权限)。 -
codename
:权限的代码名称,用于程序中引用。
-
-
auth_user
-
用途:存储用户的基本信息。
-
字段示例:
-
id
:用户的唯一标识符。 -
username
:用户名。 -
password
:加密后的密码。 -
email
:邮箱地址。 -
is_staff
、is_superuser
:是否为管理员或超级用户。 -
date_joined
:注册日期。
-
-
auth_user_groups
-
用途:关联用户与用户组的关系。
-
字段示例:
-
id
:关系记录的唯一标识符。 -
user_id
:所属用户的 ID。 -
group_id
:关联的用户组 ID。
-
-
auth_user_user_permissions
-
用途:关联用户与权限的关系。
-
字段示例:
-
id
:关系记录的唯一标识符。 -
user_id
:所属用户的 ID。 -
permission_id
:关联的权限 ID。
-
-
django_admin_log
-
用途:记录后台管理系统的操作日志。
-
字段示例:
-
id
:日志记录的唯一标识符。 -
action_time
:操作时间。 -
user_id
:执行操作的用户 ID。 -
content_type_id
:被操作对象的内容类型 ID。 -
object_id
:被操作对象的 ID。 -
object_repr
:被操作对象的表示字符串。 -
action_flag
:操作类型(如添加、修改、删除)。 -
change_message
:变更描述。
-
-
django_content_type
-
用途:存储应用中所有模型的内容类型信息。
-
字段示例:
-
id
:内容类型的唯一标识符。 -
app_label
:所属应用的标签。 -
model
:模型名称。
-
-
django_migrations
-
用途:记录数据库迁移的历史。
-
字段示例:
-
id
:迁移记录的唯一标识符。 -
app
:迁移的应用名称。 -
name
:迁移文件的名称。 -
applied
:迁移应用的时间。
-
-
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 makemigrations python 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)
一、增加数据
-
使用
create
方法 通过模型类.objects.create(字段=值)
的方式可以快速创建一条数据记录。例如前面已经使用过的创建部门数据。
Department.objects.create(title = "销售部")
这会在Department
表中插入一条title
为 “销售部” 的记录。
如果要创建UserInfo
表的数据,可以这样写:
UserInfo.objects.create(name="张三", password="123456", age=25)
上述代码会在UserInfo
表中插入一条用户名为 “张三”,密码为 “123456”,年龄为 25 岁的记录。
-
先实例化再保存 也可以先实例化一个模型对象,然后调用其
save
方法来保存到数据库。比如创建Role
表的数据:
role_obj = Role(caption="管理员") role_obj.save()
这种方式在需要对对象进行一些额外处理后再保存时比较有用,例如给对象的某些属性动态赋值等。
二、删除数据
-
使用
delete
方法 对于已经获取到的模型对象实例,可以调用其delete
方法来删除对应的数据记录。假设我们已经获取到了一个UserInfo
对象:
user = UserInfo.objects.get(name="张三") # 先获取到名为“张三”的用户对象 user.delete() # 删除该用户记录
也可以通过查询集批量删除数据。比如删除所有年龄小于 20 岁的用户:
UserInfo.objects.filter(age__lt=20).delete()
这里filter
方法筛选出符合条件(年龄小于 20 岁)的查询集,然后调用delete
方法将这些记录全部删除。
三、修改数据
-
先获取对象再修改属性并保存 先从数据库中获取到要修改的模型对象,然后修改其属性值,最后调用
save
方法保存修改。例如修改 “销售部” 部门名称为 “市场销售部”:
department = Department.objects.get(title="销售部") department.title = "市场销售部" department.save()
-
使用
update
方法批量修改 如果要批量修改满足一定条件的数据,可以使用update
方法。比如将所有用户的年龄都增加 1 岁:
UserInfo.objects.all().update(age=models.F('age') + 1)
这里models.F
对象用于在不获取具体值的情况下对字段进行操作,实现直接在数据库层面的计算更新。
四、查询数据
使用get
方法获取单个对象 get
方法用于获取满足特定条件的单个对象。例如获取名为 “张三” 的用户:
user = UserInfo.objects.get(name="张三")
注意,如果查询结果不存在或者存在多条满足条件的记录,get
方法会抛出异常(DoesNotExist
或MultipleObjectsReturned
)。
使用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 %}
效果图: