49. django之视图层函数_静态文件_request对象_ORM
1. 视图层三个常用函数
1.1 HttpResponse
HttpResponse用于返回字符串类型的数据。例如,当需要直接向浏览器返回一段文本信息时,就可以使用它。
代码示例:
(1)在user应用的views.py中导入该模块,定义login函数
(2)urls.py中导入login,添加对应关系
(3)运行django项目
1.2 render
render函数用于返回HTML文件,并且支持模板语法,可以实现动态页面的渲染。它允许我们将数据传递给HTML模板,并在模板中使用这些数据来生成最终的HTML页面。
代码示例:
(1)user应用下新建templates文件夹,新建index.html文件
(2)user的view.py中定义index函数
(3)urls.py中导入函数,添加对应关系
(4)运行项目
(5)补充知识点
[5.1]定义视图函数
def index(request):
# 返回页面对象
return render(request, 'index.html')
定义每一个视图函数都必须有一个位置参数request
render(request, template_name, context=None, content_type=None, status=None, using=None)
request:当前的 request 对象
template_name:当前需要渲染的模板文件的名字,放在 templates 文件夹里面的
context:jinja2 语法 给前端传递数据 render({"key":"value"}) === context
content_type:定义响应文档的类型 text/html / json
status:响应状态码 默认的状态码就是 200 OK
using:执行使用的是哪个模板引擎 使用默认的
[5.2]定义模板文件
可以在项目根目录下手动创建一个static文件夹用来存储(CSS、JavaScript、图片等)静态文件
模板文件路径为: user/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../../static/jquery.min.js"></script>
<link href="../../static/bootstrap.min.css" rel="stylesheet">
<script src="../../static/bootstrap.min.js"></script>
</head>
<body>
<h1>这是 index 页面</h1>
</body>
</html>
当在模板文件中引入静态文件时,上方代码中一个点表示该模板文件,每增加一个点向上增加一级,四个点即项目根目录
1.3 redirect
redirect用于实现重定向,可以将用户从一个页面跳转到另一个页面。括号内可以填写其他网站的完整URL,也可以是自己网站的某个路由后缀。
代码示例:
(1)定义函数
(2)添加对应关系
(3)运行项目
浏览器输入register自动重定向到login
(4)补充知识点
[4.1]参数之目标地址
redirect(to, *args, permanent=False, **kwargs)
to:想要重定向的目标地址
如果写详细的地址:https://www.ox.ac.uk,会重定向到该地址上
def register(request):
print('欢迎来到注册函数')
# 重定向路由
return redirect('https://www.ox.ac.uk/')
如果简写成/index/会将127.0.0.1:8080/register重定向到127.0.0.1:8080/index上
def register(request):
print('欢迎来到注册函数')
# 重定向路由
return redirect('/index/')
如果写成index/会使用127.0.0.1:8080/register对index进行拼接
def register(request):
print('欢迎来到注册函数')
# 重定向路由
return redirect('index/')
[4.2]临时重定向、永久重定向
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。 # 可以通过 回退回去
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。 # 不可以通过 回退回去
2. 静态文件
2.1 概念
在Django项目中,没有默认的名称为static的文件夹。
通常,静态文件(如CSS、JavaScript、图片img、视频video、bootstrap框架等)需要手动创建一个static文件夹来存放,这个文件夹可以放在项目的根目录下。
2.2 静态文件配置
[1] 后端
settings.py中默认有STATIC_URL = '/static/',该配置类似于访问静态文件的令牌
在settings.py中增加一个参数,STATICFILES_DIRS = ["static"],该static目录在根目录下
进行后端配置后,即可通过完整路径访问
[2] 前端
前端可以使用语法对路径进行简写
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{% static 'plugins/jQuery.js'%}s"></script>
</head>
<body>
<p>索引页面</p>
</body>
</html>
3. request对象
3.1 引入
static的plugins目录下添加bootstrap、jquery文件
user应用的templates文件夹中创建login.html文件,引入bootstrap、jquery
views.py中定义login函数,返回login.html页面对象
urls.py中添加对应关系
以form表单为例,编写完整的login.html代码

{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="{% static 'plugins/jQuery.js' %}"></script> <script src="{% static 'plugins/bootstrap.js' %}"></script> <link rel="stylesheet" href="{% static 'plugins/bootstrap.css' %}"> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">欢迎来到登陆页面</h1> {# action : 数据提交地址,不写默认提交到当前地址,写了则为指定地址 #} {# method : 请求方式,get、post #} <form action="" method="get"> <div class="form-group"> <label for="inputUsername">Username</label> <input type="text" class="form-control" id="inputUsername" name="username" placeholder="Username"> </div> <div class="form-group"> <label for="inputPassword">Password</label> <input type="password" class="form-control" id="inputPassword" name="password" placeholder="Password"> </div> <label class="checkbox-inline"> <input type="checkbox" id="inlineCheckbox1" name="hobby" value="music"> music </label> <label class="checkbox-inline"> <input type="checkbox" id="inlineCheckbox2" name="hobby" value="run"> run </label> <label class="checkbox-inline"> <input type="checkbox" id="inlineCheckbox3" name="hobby" value="dance"> dance </label> <br> <button type="submit" class="btn btn-default">Submit</button> </form> </div> </div> </div> </body> </html>
当以上代码为get请求时,会将请求参数携带在请求路径上
当请求为post时:
在浏览器中临时修改为post
post的请求路径上没有参数
报了以上错误,解决方法是将settings.py中MIDDLEWARE的csrf相关注释掉
注释之后post请求输入用户名、密码进行submit不会再报错
3.2 request对象属性
[1]查看request有哪些属性
在views.py中打印request的属性
当浏览器中触发login时:
[2] 获取某个请求具体信息
在view.py中打印request的method
当前端访问login触发login函数时,即打印该方法
[3] 获取get请求的请求体参数
login.html代码:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{% static 'plugins/jQuery.js' %}"></script>
<script src="{% static 'plugins/bootstrap.js' %}"></script>
<link rel="stylesheet" href="{% static 'plugins/bootstrap.css' %}">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center">欢迎来到登陆页面</h1>
{# action : 数据提交地址,不写默认提交到当前地址,写了则为指定地址 #}
{# method : 请求方式,get、post #}
<form action="" method="get">
<div class="form-group">
<label for="inputUsername">Username</label>
<input type="text" class="form-control" id="inputUsername" name="username" placeholder="Username">
</div>
<div class="form-group">
<label for="inputPassword">Password</label>
<input type="password" class="form-control" id="inputPassword" name="password"
placeholder="Password">
</div>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox1" name="hobby" value="music"> music
</label>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox2" name="hobby" value="run"> run
</label>
<label class="checkbox-inline">
<input type="checkbox" id="inlineCheckbox3" name="hobby" value="dance"> dance
</label>
<br>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</body>
</html>
一个键一个值的情况:
当前端提交数据时,即可获取请求体参数
一个键多个值的情况:
对于一个键多个值,get 只会获取列表最后一个元素,getlist 直接将列表取出(多选项)
4. django连接MySQL数据库
4.1 查看默认数据库
在settings.py中,有一个配置项是配置数据库的
django默认使用sqlite3数据库
4.2 指定数据库
[1] 修改为MySQL数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "django_db", # 数据库名字
"USER": "root", # 数据库实际用户名
"PASSWORD": "123456789", # 数据库实际密码
"HOST": "127.0.0.1", # 数据库 IP
"PORT": 3306,
"CHARSET": "utf8mb4", # 数据库编码
}
}
修改完成后启动django项目报错
[2] 解决以上报错的方法
(1) 猴子补丁
安装pymsql:pip install pymysql (如已安装可忽略此步)
在_ _init_ _.py中添加以下代码
import pymysql
pymysql.install_as_MySQLdb()
重启项目后报找不到库的错误
创建该数据库,重启django项目,不再报错
(2)安装第三方模块
pip install mysqlclient
MacOS无法通过pip安装mysqlclient
Windows安装后重启django项目不再报错
5. ORM介绍
5.1 概念
[1] 什么是ORM
ORM是一种将对象与关系型数据库之间的映射的技术,主要实现了以下三个方面的功能:
数据库中的表映射为Python中的类
数据库中的字段映射为Python中的属性
数据库中的记录映射为Python中的实例
ORM的主要优点是可以减少开发人员编写重复的SQL语句的时间和工作量,并且可以减少由于SQL语句的调整和更改所带来的错误。
[2] Django ORM的优点
与其他ORM框架相比,Django ORM拥有以下优点:
简单易用:Django ORM的API非常简单,易于掌握和使用。
丰富的API:Django ORM提供了丰富的API来完成常见的数据库操作,如增删改查等,同时也支持高级查询和聚合查询等操作。
具有良好的扩展性:Django ORM可以与其他第三方库进行无缝集成,如Django REST framework、Django-Oscar等。
自动映射:Django ORM支持自动映射,开发者只需要定义数据库表的结构,就可以自动生成相应的Python类,从而减少开发过程中的重复代码量。
5.2 ORM表操作
[1] 定义模型表
根据概念,在python中定义类转换为数据库中的表
在应用--models.py文件中定义模型表
from django.db import models
# Create your models here.
class Student(models.Model): # 定义学生类(学生表),此文件中的类必须继承models.Model
name = models.CharField(max_length=32) # 类比于数据库的name varchar(32)
age = models.IntegerField() # 类比于数据库的age int()
[2] 数据库迁移
方式一:命令行
(1)生成迁移文件
此步骤将操作记录在migrations文件夹中,虽然文件夹内有相关文件,但是没有同步到数据库中,所以数据库是没有数据的
运行命令需要在有manage.py的路径下
生成0001_initial.py文件
在setttings.py中会默认配置数据库的id
(2)启动迁移任务
将操作同步到数据库
方式二:task任务
Tools -> run manage.py task ---> makemigrations ---> migrate
新建的club表被同步到数据库
[3] 表名称
以上从python类同步到数据库后,表名称为:应用名_类名
在python类下配置一个Meta类,则数据库中的表名称以Meta类中定义为准
class Student(models.Model): # 定义学生类(学生表),此文件中的类必须继承models.Model
name = models.CharField(max_length=32) # 类比于数据库的name varchar(32)
age = models.IntegerField() # 类比于数据库的age int()
class Meta:
db_table = "student"
5.3 ORM字段操作
[1] 增加字段
增加一个grade字段
class Student(models.Model): # 定义学生类(学生表),此文件中的类必须继承models.Model
name = models.CharField(max_length=32) # 类比于数据库的name varchar(32)
age = models.IntegerField() # 类比于数据库的age int()
grade = models.IntegerField()
进行数据库的重新迁移:makemigrations--migrate
出现以下提示:
1) 现在提供一次性默认值(将在所有现有行上设置此列的空值)
2) 退出,让我在models.py中添加一个默认值
选择2退出,给grade默认空值即可
class Student(models.Model): # 定义学生类(学生表),此文件中的类必须继承models.Model
name = models.CharField(max_length=32) # 类比于数据库的name varchar(32)
age = models.IntegerField() # 类比于数据库的age int()
grade = models.IntegerField(default='')
注意:字符串类型默认值default="",数字类型默认值default=None
class Student(models.Model): # 定义学生类(学生表),此文件中的类必须继承models.Model
name = models.CharField(max_length=32) # 类比于数据库的name varchar(32)
age = models.IntegerField() # 类比于数据库的age int()
a = models.IntegerField(default=None)
b = models.CharField(max_length=32, default="")
c = models.IntegerField(default=None)
重新迁移:makemigrations--migrate
[2] 删除字段
models.py中删除所要删除的字段,重新迁移:makemigrations--migrate
例:以上数据表删除c字段
class Student(models.Model): # 定义学生类(学生表),此文件中的类必须继承models.Model
name = models.CharField(max_length=32) # 类比于数据库的name varchar(32)
age = models.IntegerField() # 类比于数据库的age int()
a = models.IntegerField(default=None)
b = models.CharField(max_length=32, default="")
# c = models.IntegerField(default=None)
[3] 约束条件
含义 | sql语句 | ORM |
可以为空 | null | null=True |
不可以为空 | not null | null=False |
5.4 创建django临时环境
在django中操作模型表,必须启动django
操作模型表须在视图函数内
为了测试增删改查数据的方便,可以使用以下步骤创建django临时环境
第一步:在django项目中,定义一个scripts目录,用来存放自定义脚本,在该目录中,创建一个py文件用来测试增删改查数据
第二步:打开manage.py文件,复制main函数里第一行代码,项目名称不同则参数不同 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj2.settings')
第三步:导入django模块
第四步:导入django模型表
第五步:运行django启动命令
第六步:操作模型表
5.5 ORM数据操作
[1] 增加数据
在5.4的基础上使用临时环境进行测试
方式一(常用):
模型表.objects.create(字段名=字段值)
方式二(不常用):
模型表(字段名=字段值)
[2] 查询数据
(1)语法
获取到当前表中的全部数据:模型表名.objects.all()
根据指定条件筛选数据:
方式一:模型表名.objects.get(筛选字段名=筛选字段值)
方式二:模型表名.objects.filter(筛选字段名=筛选字段值)
去除指定条件的数据:
模型表名.objects.exclude(筛选字段名=筛选字段值)
(2)代码
all方法获取所有数据
import os
import django
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj2.settings')
django.setup()
from user.models import Student
result = Student.objects.all()
print(result) # 返回值是一个QuerySet对象,列表里存放的就是每一条记录
student_one = result[0]
print(student_one, type(student_one)) # Student object (1) <class 'user.models.Student'>
print(student_one.name)
print(student_one.age)
get方法当参数存在时就获取,不存在就报错,多于1个就报错
student_one = Student.objects.get(id=1) # 存在则获取
print(student_one.name)
student_two = Student.objects.get(id=2) # 不存在则报错
student_three = Student.objects.get(name='avril') # 多于1个也报错
filter方法当参数存在时就获取,不存在不会报错,多于1个也不会报错
import os
import django
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dj2.settings')
django.setup()
from user.models import Student
result = Student.objects.filter(id=1) # 存在则获取
print(result)
print(result[0].name)
result = Student.objects.filter(name='avril').first() # 获取第一条符合的记录
print(result)
print(result.id)
result = Student.objects.filter(name='avril').last() # 获取最后一条符合的记录
print(result)
print(result.id)
result = Student.objects.filter(id=20) # 不存在不会报错
print(result)
result = Student.objects.filter(name='avril') # 多于1个不会报错
print(result)
exclude去除掉符合条件的记录
result = Student.objects.exclude(id=14) # 去除掉id为14的记录
print(result)
[3] 删除数据
方式一:过滤后直接删除
Student.objects.filter(id=14).delete()
如果有多条记录符合括号过滤参数,则会删除所有符合的记录
方式二:先过滤出对象,再删除对象
obj = Student.objects.get(id=15)
obj.delete()
[4] 修改数据
方式一:查询并直接修改
模型表.objects.filter(属性名=属性值).update(新的参数)
result = Student.objects.filter(id=4).update(name='ronaldo')
print(result)
result2 = Student.objects.filter(name='avril').update(age=19)
print(result2)
返回值是修改记录的条数
方式二:先查询得到对象,再修改对象
obj = Student.objects.get(id=4)
obj.name = 'cristiano'
obj.save() # save()保存不能忽略