【3.0】Django框架之数据操作初识
【一】登录功能实现
【1】form表单默认是post请求
- 添加的数据会默认拼接在url后面
<form action=""></form>
http://127.0.0.1:8000/login/?username=dream&password=521
【2】form表单的action参数
- 不写,向当前所在的url提交数据
- 全写,向指定url提交数据
- 只写后缀
在前期我们使用django提交post请求时,需要修改配置文件中的一项配置
- 将中间件禁掉,不走中间件传输数据
- settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
【3】请求方式的不同返回信息不同
def login(request):
'''
get 请求和 post 请求应该具有不同的处理机制
:param request:
:return:
'''
# (1) 获取 请求方式 并且是全大写字符串
if request.method == "GET":
# 返回一个登录界面
return render(request, 'login.html')
return HttpResponse("这是get请求")
【二】request初识
【1】request.method
获取发起请求的请求方式
get请求携带的数据是由大小限制的
post请求携带的请求参数没有限制
【2】request.POST
获取用户输入的请求数据,但不包含文件
返回的是:大写字符串
【3】get/getlist
get
只会获取列表最后一个元素
getlist
直接将列表取出(多选项)
def login(request):
'''
get 请求和 post 请求应该具有不同的处理机制
:param request:
:return:
'''
# (1) 获取 请求方式 并且是全大写字符串
if request.method == "POST":
# 获取用户数据
data = request.POST
print(data)
'''
# get 只会获取列表最后一个元素
username = data.get('username')
password = data.get('password')
hobby = data.get('hobby')
'''
# getlist 获取所有值
username = data.getlist('username')
password = data.getlist('password')
hobby = data.getlist('hobby')
print(username, password, hobby)
# 获取 get 请求 网址后边携带的请求参数
data = request.GET
# 处理请求数据 同 POST
return render(request, 'login.html')
【三】操作数据库
【1】默认数据库
默认数据库:sqlite3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
【2】修改数据库
修改数据库配置
- settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day09',
'USER': 'root',
'PASSWORD': '1314521',
'HOST': '127.0.0.1',
'PORT': 3306,
'CHARSET': 'utf8',
}
}
代码声明
django 默认使用mysqldb模块链接mysql
但是该模块的兼容性不好,需要手动修改为pymysql链接
在项目下的init或者任意的应用名下的init文件中书写一下代码
- init.py
import pymysql
pymysql.install_as_MySQLdb()
【四】django ORM
ORM ---- 对象映射关系
作用:能够让一个不会用sql语句操控数据库的小白也能通过python 面向对象的代码简单快捷的操作数据库
不足之处:封装程度不高,有时候sql语句的效率偏低,需要自己写sql语句
应用下的models.py文件中修改
【1】在models.py中建表
from django.db import models
# Create your models here.
class User(models.Model):
# id int primary key auto_increment
id = models.AutoField(primary_key=True)
# username varchar(32)
username = models.CharField(max_length=32)
# password int
password = models.IntegerField()
【2】数据库迁移命令
- 将操作记录记录在migrations文件夹
python39 manage.py makemigrations
- 将操作同步到真正的数据库
python39 manage.py migrate
只要修改了models中有关数据库相关的代码,就必须执行上面的数据库迁移命令
- app01_user
- 我们通过orm创建的表
- 一个项目可能有多个应用,在前面加上前缀是为了防止表明冲突造成数据错乱
- models.py
from django.db import models
# Create your models here.
class User(models.Model):
# id int primary key auto_increment
id = models.AutoField(primary_key=True)
# username varchar(32)
username = models.CharField(max_length=32,verbose_name="用户名")
# CharField : 必须指定 max_length 参数 ,不指定就会报错
# verbose_name : 该参数所有字段都可以使用,就是一个注释语法
# password int
password = models.IntegerField()
class Author(models.Model):
# 由于一张表中必须要有一个主键字段,并且一般情况下都叫id字段
# 所有当我们没有定义 主键 id字段 的时候,orm会帮我们创建一个名为 id 的主键字段
# 也就意味着后续我们在创建模型表的时候,如果主键字段名没有额外的叫法,那么主键字段可以省略不写
# username varchar(32)
username = models.CharField(max_length=32)
# password int
password = models.IntegerField()
修改数据库操作时候,一定要进行数据库的重加载(我自己的叫法)
【五】字段的增删改查
【1】字段的添加
【1】在终端给出默认值
- 直接在终端给出默认值
【2】允许为空
- 给语句增加一条
null=True
【3】主动设置默认值default="music"
- 提前设定好默认值
【4】代码
from django.db import models
# Create your models here.
class User(models.Model):
# id int primary key auto_increment
id = models.AutoField(primary_key=True)
# username varchar(32)
username = models.CharField(max_length=32, verbose_name="用户名")
# CharField : 必须指定 max_length 参数 ,不指定就会报错
# verbose_name : 该参数所有字段都可以使用,就是一个注释语法
# password int
password = models.IntegerField()
# *******
# (1)添加字段:年龄,若表内已经存在数据,而要添加额外的字段需要给默认值
age = models.IntegerField(verbose_name="年龄")
# (2)添加允许为空字段
info = models.CharField(verbose_name="个人简介", max_length=32, null=True)
# (3)提前设定好默认值
hobby = models.CharField(verbose_name="爱好", max_length=32, default="music")
# *******
class Author(models.Model):
# 由于一张表中必须要有一个主键字段,并且一般情况下都叫id字段
# 所有当我们没有定义 主键 id字段 的时候,orm会帮我们创建一个名为 id 的主键字段
# 也就意味着后续我们在创建模型表的时候,如果主键字段名没有额外的叫法,那么主键字段可以省略不写
# username varchar(32)
username = models.CharField(max_length=32)
# password int
password = models.IntegerField()
【2】字段的更改
- 直接修改源码,再进行数据库重载
from django.db import models
# Create your models here.
class User(models.Model):
# id int primary key auto_increment
id = models.AutoField(primary_key=True)
# username varchar(32)
username = models.CharField(max_length=32, verbose_name="用户名")
# CharField : 必须指定 max_length 参数 ,不指定就会报错
# verbose_name : 该参数所有字段都可以使用,就是一个注释语法
# password int
# password = models.IntegerField()
# *******由原来的字段修改为新的字段*******
password = models.CharField(verbose_name="密码", max_length=64)
# (1)添加字段:年龄,若表内已经存在数据,而要添加额外的字段需要给默认值
age = models.IntegerField(verbose_name="年龄")
# (2)添加允许为空字段
info = models.CharField(verbose_name="个人简介", max_length=32, null=True)
# (3)提前设定好默认值
hobby = models.CharField(verbose_name="爱好", max_length=32, default="music")
class Author(models.Model):
# 由于一张表中必须要有一个主键字段,并且一般情况下都叫id字段
# 所有当我们没有定义 主键 id字段 的时候,orm会帮我们创建一个名为 id 的主键字段
# 也就意味着后续我们在创建模型表的时候,如果主键字段名没有额外的叫法,那么主键字段可以省略不写
# username varchar(32)
username = models.CharField(max_length=32)
# password int
password = models.IntegerField()
【3】删除字段
-
直接注释源码
-
再进行重载数据库
一旦删除字段,字段下所在的数据也会同时消失,一定要小心
重载之前一定要确认数据
【六】数据的增删改查
【1】查询数据
from django.shortcuts import render, HttpResponse, redirect
from app01 import models
# Create your views here.
def login(request):
'''
get 请求和 post 请求应该具有不同的处理机制
:param request:
:return:
'''
# (1) 获取 请求方式 并且是全大写字符串
if request.method == "POST":
# 获取用户数据
data = request.POST
# print(data)
'''
# get 只会获取列表最后一个元素
username = data.get('username')
password = data.get('password')
hobby = data.get('hobby')
'''
# # getlist 获取所有值
# username = data.getlist('username')
# password = data.getlist('password')
# hobby = data.getlist('hobby')
#
# print(username, password, hobby)
# --------------------------
# 获取用户输入的用户名和密码
username = data.get('username')
password = data.get('password')
# 向数据库查询数据
res = models.User.objects.filter(username=username)
print(res)
# 返回的是[数据对象1,数据对象2]
# 数据对象支持索引取值
user_obj = res[0]
print(user_obj.username)
print(user_obj.password)
# 获取 get 请求 网址后边携带的请求参数
data = request.GET
# 处理请求数据 同 POST
return render(request, 'login.html')
# 向数据库查询数据
res = models.User.objects.filter(username=username)
print(res)
# 返回的是[数据对象1,数据对象2]
# 数据对象支持索引取值
user_obj = res[0]
print(user_obj.username)
# dream
print(user_obj.password)
# 521
- 返回值类似于列表套对象
- 支持索引取值,支持切片,但是不支持负数索引取值
- 不推荐索引取值
【2】数据的增加
def register(request):
# 先给用户返回一个注册页面
if request.method == 'POST':
data = request.POST
username = data.get('username')
password = data.get('password')
# # 直接获取用户输入的数据存储进数据库
# # (1)第一种直接添加
# res = models.User.objects.create(username=username, password=password)
# # 返回值就是当前被创建的对象本身
# print(res)
# (2) 第二种 创建类对象
user_obj = models.User(username=username, password=password)
# 保存数据
user_obj.save()
return render(request, 'register.html')
【3】用户操作数据的更改
- 先从数据库中将数据全部展示到前端,然后添加两个按钮,一个编辑,一个删除
(1)编辑功能
点击编辑按钮,向后端发送编辑数据的请求
- 如何告诉用户想要编辑哪条数据?
- 将编辑按钮所在的信息的主键值发送给后端
- 在URL的
?
中携带参数
- 在URL的
- 将编辑按钮所在的信息的主键值发送给后端
- 后端拿到用户想要编辑的数据对象,展示到前端页面供用户查看和编辑
查询数据
def resetdata(request):
# 查询用户表内的所有数据
# 方式一
# data = models.User.objects.filter()
# 方式二
user_queryset = models.User.objects.all()
return render(request, 'resetdata.html', locals())
用户数据展示
<tbody>
{% for user_obj in user_queryset %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td>
<a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-success btn-primary">编辑</a>
<a href="" class="btn btn-danger btn-primary">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
编辑数据
def edit_user(request):
# 获取URL后面拼接的用户ID
edit_id = request.GET.get('user_id')
# 查询当前用户想要编辑的用户对象
edit_obj = models.User.objects.filter(id=edit_id).first()
# 编辑用户
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
# 在数据库中修改数据
# 修改数据方式一
# 将 filter 查询出的列表内的所有的对象全部更新 ---- 批量更新操作
# 只修改被修改的字段
# models.User.objects.filter(id=edit_id).update(username=username, password=password)
# 编辑完后跳转到展示与用户数据页面
# 修改数据方式二
# 局部更新
# 当字段特别多的时候,效率会非常低
# 从头到尾将数据的所有字段更新一遍,无论字段是否被改变
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
return redirect('/resetdata/')
# 将数据对象展示到页面上
return render(request, 'edituser.html', locals())
用户数据展示页面
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 本地 链接 引入方法 -->
<!-- Websource 文件夹 拷贝到当前文件夹下即可使用 -->
<!-- jQuery 文件 -->
<script src="{% static 'plugins/Bootstrap/js/bootstrap.min.js' %}"></script>
<!-- Bootstrap 的 JS 文件 (动画效果需要jQuery) -->
<script src="{% static 'js/jquery.min.js' %}"></script>
<!-- Bootstrap 的 CSS 样式文件 -->
<link rel="stylesheet" href="{% static 'plugins/Bootstrap/css/bootstrap.min.css' %}">
<!-- bootstrap-sweetalert(弹框) 的 CSS 文件 -->
<link rel="stylesheet" href="{% static 'plugins/bootstrap-sweetalert/dist/sweetalert.css' %}">
<!-- bootstrap-sweetalert(弹框) 的 JS 文件 -->
<script src="{% static 'plugins/bootstrap-sweetalert/dist/sweetalert.min.js' %}"></script>
<!-- 以下为 css样式书写区 -->
<style>
</style>
</head>
<body>
{#拿到用户数据#}
{{ user_queryset }}
<h1 class="text-center">用户数据展示</h1>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>ID</th>
<th>USERNAME</th>
<th>PASSWORD</th>
<th>ACTION</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_queryset %}
<tr>
<td>{{ user_obj.id }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td>
<a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-success btn-primary">编辑</a>
<a href="" class="btn btn-danger btn-primary">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
编辑用户数据页面
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 本地 链接 引入方法 -->
<!-- Websource 文件夹 拷贝到当前文件夹下即可使用 -->
<!-- jQuery 文件 -->
<script src="{% static 'plugins/Bootstrap/js/bootstrap.min.js' %}"></script>
<!-- Bootstrap 的 JS 文件 (动画效果需要jQuery) -->
<script src="{% static 'js/jquery.min.js' %}"></script>
<!-- Bootstrap 的 CSS 样式文件 -->
<link rel="stylesheet" href="{% static 'plugins/Bootstrap/css/bootstrap.min.css' %}">
<!-- bootstrap-sweetalert(弹框) 的 CSS 文件 -->
<link rel="stylesheet" href="{% static 'plugins/bootstrap-sweetalert/dist/sweetalert.css' %}">
<!-- bootstrap-sweetalert(弹框) 的 JS 文件 -->
<script src="{% static 'plugins/bootstrap-sweetalert/dist/sweetalert.min.js' %}"></script>
<!-- 以下为 css样式书写区 -->
<style>
</style>
<body>
<h1 class="text-center">信息编辑功能</h1>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-offset-2">
<form action="" method="post">
<p>username:<input type="text" name="username" class="form-control" value="{{ edit_obj.username }}"></p>
<p>password<input type="password" name="password" class="form-control" value="{{ edit_obj.password }}"></p>
<input type="submit" class="btn btn-success btn-block" value="编辑">
</form>
</div>
</div>
</div>
</body>
</html>
路由层
"""day02 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('register/', views.register),
# 查询所有用户信息
path('resetdata/', views.resetdata),
# 编辑用户信息
path('edit_user/', views.edit_user),
]
(2)删除功能
- 跟编辑功能逻辑类似
删除功能
def del_user(request):
# 获取用户想要删除的用户ID
del_user_id = request.GET.get('user_id')
# 拿到用户对象并删除
# 批量删除
models.User.objects.filter(id=del_user_id).delete()
# 删除成功,跳转到展示页面
return redirect('/resetdata/')
路由层
"""day02 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('register/', views.register),
# 查询所有用户信息
path('resetdata/', views.resetdata),
# 编辑用户信息
path('edit_user/', views.edit_user),
# 删除用户数据
path('del_user/', views.del_user),
]
- 真正的删除数据操作,需要二次确认!
- 删除数据,内部其实不是真正的删除数据
- 我们会给数据添加一个删除字段来表示数据是否被删除了,如果数据被删除了,仅仅只是修改字段的状态值
本文来自博客园,作者:Chimengmeng,转载请注明原文链接:https://www.cnblogs.com/dream-ze/p/17559589.html