Django静态文件配置与request对象方法
一、静态文件与配置
在平时,我们之所以能够在浏览器里面输入网址就可拿到对应的资源,是因为开发者开设了该资源对应的访问接口,所以我们能够访问到对应的资源。
1.静态文件
- 所谓静态文件:写好之后不会自动动态改变的文件资源,比如我们写好的css文件、js文件、图片文件、第三方框架文件
- 我们默认将所有的静态文件都放在一个static文件夹内,static目录下基本还会再分几个文件夹,我们的css文件,js文件,图片文件、第三方文件资源等都放在这下面
- 在Django项目中是没有这些文件夹的需要我们手动创建。
示例:
举个栗子:在加在静态资源的时候没有开设对应的访问接口
我们先来运行一个Django项目并创建一个static静态文件夹。
urls.py文件:
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
]
views.py文件:
def login(requset):
return render(requset,'login.html')
login.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
<link rel="stylesheet" href="../static/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css">
<script src="../static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-lg-8 col-md-offset-2"></div>
</div>
</div>
</body>
</html>
接下来我们启动Django项目并访问,如下:
我们在login右键点击检查,打开网络控制台,刷新页面,如下:
看到bootstrap框架报错:404,接下来我们点进去看一下:
然后我们复制请求URL,在浏览器中打开:
还是报错,请求的资源不存在!我们明明已经导入了啊!这是为何呢?static路径等都没有问题啊!
这是因为我们根本没有开设该资源对应的接口!所以无法访问!
2.静态文件配置
为了解决上面的问题,我们setting.py加入如下代码,也就是静态文件配置:
# setting.py文件:静态文件配置,可以配置多个
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
]
静态文件配置就是将static的文件路径加入。
然后我们再来访问页面,重新启动Django项目。
3.静态文件进阶操作
针对以上操作,你是不是有很多疑问?小脑袋瓜子是不是充满了很多问号?
首先,我们来介绍一下,接口前缀。
3.1 接口前缀
- 所谓接口前缀,就是相当于一个令牌
- 如果你想要访问静态文件资源,那么必须以static开头,你书写了接口前缀之后 就拥有了访问下列列表中所有文件夹内部资源的权限。
- 默认书写在
setting.py
文件中,可有多个接口,从上往下依次查找,都没有就会报错。
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀,这就是接口前缀
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"), # 静态文件存放位置
os.path.join(BASE_DIR,'static1'), #可以开设多个接口
os.path.join(BASE_DIR,'static2'),
]
比如,来上面的例子,因为接口前缀匹配到<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
以static
文件开头,并且开设了对应文件的接口,所以才会访问到以上资源。
不信,我们来验证:
3.2 验证:
首先,我们新建static1,static2,static1下面新建a.txt,static2下面新建b.txt。
内容如下:
static1下面的a.txt内容
I'm static A
static2下面的b.txt内容
I'm static B
然后启动项目,我们来访问:
还不信的话,我们来修改一下STATIC_URL = '/static/'
,如图所示:
然后重启项目访问。
补充:
当你在写Django项目的时候,可能回出现后端代码修改了但是前端页面没有变化的情况:
1.你在同一个窗口开了好几个Django项目,一直在跑的其实是第一个Django项目
2.取消网页浏览器缓存
右键--》检查--》shortcuts--》Preferences--》Disable cache...
Edge浏览器:(中文是不是看起来很舒适?)
谷歌浏览器
3.3 动态解析
接着上面的示例,我们再来启动Django项目。
然后我们把令牌改为Shawn
,接着又可以了。
这时,产品经理拍着你的肩膀突然来一句说:这样不好,在改一下..
然后你又要改回去,就这样反反复复。
于是就出现了动态解析。
动态解析模板语法:
{% load static %} 模板语法
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
然后我们将模板语法加入html文件中,然后重启Django项目。
我们在来修改令牌,然后随便你怎么改,令牌都可以动态解析到,都可以访问到资源。
还不明白?我们来看一张图,有图有真相:
二、request对象方法
1.form表单回顾
- 作用:将用户输入的数据提交到后端,默认使用的是
get
请求。
2. form表单三个属性:
2.1 action参数
作用:控制后端提交的路径
三种书写方式:
- 不写:默认朝当前页面地址提交数据
- 只写后缀:/index/,将当前服务端的ip+port拼接到后缀前面然后访问
- 全写:https://www.mzitu.com,向指定地址提交数据(指名道姓)
示例:比如我们写一个简单的登录页面
继续使用上面的代码,login.html
文件内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{# <link rel="stylesheet" href="/shawn/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css">#}
{# <script src="/shawn/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>#}
{% load static %} {#模板语法,类似于导模块#}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-lg-8 col-md-offset-2"></div>
<form action="">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-success btn-block">
</form>
</div>
</div>
</body>
</html>
view.py文件
from django.shortcuts import render
# Create your views here.
def login(requset):
print("我看你骨骼惊奇,来来看我的博客吧!")
return render(requset,'login.html')
get请求:
不写
或者只写后缀:
然后提交数据
然后惊奇的发现我们提交的数据都跑到URLhttp://127.0.0.1:8888/login/?username=123&password=123
里面去了,并没有提交到后端。
这是因为action参数默认使用的是get请求,pycharm内打印出如下内容:
2.2 method参数:
作用:指定请求的方式
请求方式:
-
get请求:数据是直接放在URL后面的, 以"?"分割URL和传输数据,参数之间以"&"相连
例如:
http://127.0.0.1:8888/login/?username=123&password=123
-
post请求:把提交的数据放在HTTP包的请求体中,不会显示到URL中,就是隐藏起来。
示例:在form表单中加入method参数将请求方式改为post请求,再次启动Django项目。
post请求:
在login.html修改文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{# <link rel="stylesheet" href="/shawn/bootstrap-3.3.7-dist/css/bootstrap-theme.min.css">#}
{# <script src="/shawn/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>#}
{% load static %} {#模板语法,类似于导模块#}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-lg-8 col-md-offset-2"></div>
<form action="login.html " method="post">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-success btn-block">
</form>
</div>
</div>
</body>
</html>
然后点击提交:
结果报错403:请求资源不可用,拒绝访问。
这是因为中间件的作用(暂时不用理解): 需要注释setting.py
文件里MIDDLEWARE
中一行内容
刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。
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',
]
注释掉之后,然后我们再来重新提交数据,pycharm打印出如下:
3.request对象方法
3.1 request.method
- 获取当前请求的请求方法并且结果是一个纯大写的字符串类型
示例:获取当前请求方法
view.py文件
from django.shortcuts import render
# Create your views here.
def login(requset):
print(requset.method, type(requset.method)) # 获取当前请求数据的方法,并且结果是一个纯大写的字符串类型
# 返回给浏览器一个登录页面
return render(requset, 'login.html')
然后在浏览器提交表单
pycharm显示如下,然后就可以获取到当前的请求方法:
通常呢,我们使用get请求返回一个页面,而post情求获取用户信息,数据校验等一些复杂的操作,那我们在这里如何实现呢?
简单,只需要写个if判断即可。
view.py文件
from django.shortcuts import render, HttpResponse
# Create your views here.
def login(requset):
# print(requset.method, type(requset.method)) # 获取当前请求数据的方法,并且结果是一个纯大写的字符串类型 <class 'str'>
if requset.method == "GET":
# 返回给浏览器一个登录页面
return render(requset, 'login.html')
elif requset.method == "POST":
# POST 请求提交数据
return HttpResponse("好好学习,天天向上!")
然后使用POST请求向后端提交数据,而使用GET请求就会返回一个页面。
但是,你有没有发现这样写的话后面代码写多了就会使层级变得复杂。
因为视图函数默认就是用来处理get请求的,所以我们将代码精简如下:
视图函数固定格式:
from django.shortcuts import render, HttpResponse,redirect
# Create your views here.
def login(requset):
if requset.method == "POST": # POST 请求提交数据
return HttpResponse("好好学习,天天向上!")
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
解决了上面问题,那么我们怎么去获取用户请求数据呢?
首先我们打开断点调试,然后在浏览器提交数据,就可以看到我们刚刚提交的数据了。
任意一个出现request对象出现的行加上断电调试,然后DEBUG模式运行,可以获取到request对象的方法
3.2 request.POST
- 获取用户提交的POST请求数据(不包含文件)
- 数据类型:返回的是一个字典类型
views.py文件
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get 情请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
#<QueryDict: {'username': ['1314'], 'password': ['1414']}>
return HttpResponse("好好学习,天天向上!")
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
浏览器提交数据,pycharm打印如下:
然后我们再来获取用户名,看看它到底是什么数据类型。
requset.POST.get
- get方法会获取列表最后一个元素
我们在views.py文件加入get方法:
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get 情请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
# <QueryDict: {'username': ['1314'], 'password': ['1414']}>
username = requset.POST.get("username") # get方法会只会得到列表最后一个元素
print(username, type(username)) # 1314 <class 'str'>
return HttpResponse("好好学习,天天向上!")
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
提交数据后,得到一个字符串的数据类型。
而且,get方法会获取列表最后一个元素,不信,我们来验证一下:
在login.html文件中多添加一个用户名。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{% load static %} {#模板语法,类似于导模块#}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-md-8 col-md-offset-2">
<form action="login.html " method="post">
username:
<input type="text" name="username" class="form-control">
<input type="text" name="username" class="form-control">
password:
<input type="password" name="password" class="form-control">
<input type="submit" class="btn btn-success btn-block">
</form>
</div>
</div>
</div>
</body>
</html>
然后前端提交不同的两个用户名,如下:
然后得到列表最后一个元素。
问题又来了,如果获取用户的爱好呢?用户的爱好是可以有多个的那么怎么样去获取呢?
login.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{% load static %} {#模板语法,类似于导模块#}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-md-8 col-md-offset-2">
<form action="login.html " method="post">
username:
<input type="text" name="username" class="form-control">
username:
<input type="text" name="username" class="form-control">
password:
<input type="password" name="password" class="form-control">
<input type="submit" class="btn btn-success btn-block">
<p>
<input type="checkbox" name="hobby" value="bas">篮球
<input type="checkbox" name="hobby" value="foot">足球
<input type="checkbox" name="hobby" value="study">学习
</p>
</form>
</div>
</div>
</div>
</body>
</html>
request.POST.getlist
- 获取整个列表
views.py文件
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get 情请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
# <QueryDict: {'username': ['1314'], 'password': ['1414']}>
username = requset.POST.get("username")
passwd =requset.POST.get("password")
print(username, type(username)) # 1314 <class 'str'>
hobby =requset.POST.getlist('hobby') # 获取整个列表
print(username,passwd,hobby)
return HttpResponse("好好学习,天天向上!")
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
前端提交数据,然后后端获取到的数据如下:
3.3 request.GET
-
获取url问号后面的数据
-
数据类型:返回的是一个字典类型
views.py文件
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
# <QueryDict: {'username': ['1314'], 'password': ['1414']}>
username = requset.POST.get("username")
passwd =requset.POST.get("password")
print(username, type(username)) # 1314 <class 'str'>
hobby =requset.POST.getlist('hobby') # 获取整个列表
print(username,passwd,hobby)
return HttpResponse("好好学习,天天向上!")
print(requset.GET) # <QueryDict: {'username': ['lili'], 'password': ['123']}>
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
前端提交urlhttp://127.0.0.1:8888/login/login.html/?username=lili&password=123
后端返回数据:
它和POST一样都有两个方法:
request.GET.get
- get方法会获取列表最后一个元素
request.GET.getlist
- 获取到整个列表
views.py文件
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get 情请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
# <QueryDict: {'username': ['1314'], 'password': ['1414']}>
username = requset.POST.get("username")
passwd =requset.POST.get("password")
print(username, type(username)) # 1314 <class 'str'>
hobby =requset.POST.getlist('hobby') # 获取整个列表
print(username,passwd,hobby)
return HttpResponse("好好学习,天天向上!")
print(requset.GET)
print(requset.GET.get('username'))
print(requset.GET.getlist('hobby'))
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
前端提交urlhttp://127.0.0.1:8888/login/login.html/?username=lili&password=123
后端输出数据如下:
接下来我盟再来看看如何获取文件。
3.4 request.FILES
- 获取用户上传的文件数据
- 直接看成是字典即可
request.FILES.get
- 获取列表最后一个元素
request.FILES.getlist
- 获取整个列表
login.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{% load static %} {#模板语法,类似于导模块#}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-md-8 col-md-offset-2">
<form action="login.html " method="post">
username:
<input type="text" name="username" class="form-control">
username:
<input type="text" name="username" class="form-control">
password:
<input type="password" name="password" class="form-control">
<input type="submit" class="btn btn-success btn-block">
<p>
<input type="checkbox" name="hobby" value="bas">篮球
<input type="checkbox" name="hobby" value="foot">足球
<input type="checkbox" name="hobby" value="study">学习
</p>
<p>
<input type="file" name="myfile">
</p>
</form>
</div>
</div>
</div>
</body>
</html>
views.py文件
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get 情请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
return HttpResponse("好好学习,天天向上!")
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
前端提交数据
后端输出如下:
并没有拿到我们需要的文件对象。
这是因为:针对文件数据,不能使用request.POST获取,该方法只能获取到文件名。
然后我们使用requset.FILES方法获取文件对象
views.py文件
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(requset):
'''
get 情请求和post情求应该有不同的处理机制
:param requset:请求相关的数据对象,里面有很多简易的方法
:return:
'''
if requset.method == "POST": # POST 请求提交数据
print(requset.POST) # 获取用户提交的POST请求 (不包含文件)
# 针对文件数据,不能使用request.POST获取,该方法只能获取到文件名。
print(requset.FILES)
return HttpResponse("好好学习,天天向上!")
return render(requset, "login.html") # 如果是get请求返回给浏览器一个登录页面
效果如下:
注意: form表单如果需要携带文件数据 那么要添加参数 : enctype="multipart/form-data"
login.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆界面</title>
{% load static %} {#模板语法,类似于导模块#}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="text-center">登陆</h1>
<div class="col-md-8 col-md-offset-2">
<form action="login.html" method="post" enctype="multipart/form-data">
username:
<input type="text" name="username" class="form-control">
username:
<input type="text" name="username" class="form-control">
password:
<input type="password" name="password" class="form-control">
<input type="submit" class="btn btn-success btn-block">
<p>
<input type="checkbox" name="hobby" value="bas">篮球
<input type="checkbox" name="hobby" value="foot">足球
<input type="checkbox" name="hobby" value="study">学习
</p>
<p>
<input type="file" name="myfile">
</p>
</form>
</div>
</div>
</div>
</body>
</html>
效果展示如下:
版权声明:
作者:淘小欣
链接:https://blog.taoxiaoxin.club/157.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。

共有 0 条评论