Django静态文件配置与request对象方法

一、静态文件与配置

在平时,我们之所以能够在浏览器里面输入网址就可拿到对应的资源,是因为开发者开设了该资源对应的访问接口,所以我们能够访问到对应的资源。

1.静态文件

  • 所谓静态文件:写好之后不会自动动态改变的文件资源,比如我们写好的css文件、js文件、图片文件、第三方框架文件
  • 我们默认将所有的静态文件都放在一个static文件夹内,static目录下基本还会再分几个文件夹,我们的css文件,js文件,图片文件、第三方文件资源等都放在这下面
  • 在Django项目中是没有这些文件夹的需要我们手动创建。

image-20210318193542034

示例:

举个栗子:在加在静态资源的时候没有开设对应的访问接口

我们先来运行一个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>

image-20210318202342015

接下来我们启动Django项目并访问,如下:

image-20210318202822145

image-20210318203026841

image-20210318203306981

image-20210318203420359

我们在login右键点击检查,打开网络控制台,刷新页面,如下:

image-20210318204030278

看到bootstrap框架报错:404,接下来我们点进去看一下:

image-20210318204425212

然后我们复制请求URL,在浏览器中打开:

image-20210318204810053

还是报错,请求的资源不存在!我们明明已经导入了啊!这是为何呢?static路径等都没有问题啊!

image-20210318204945129

这是因为我们根本没有开设该资源对应的接口!所以无法访问!

2.静态文件配置

为了解决上面的问题,我们setting.py加入如下代码,也就是静态文件配置

# setting.py文件:静态文件配置,可以配置多个
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static'),
]

静态文件配置就是将static的文件路径加入。

然后我们再来访问页面,重新启动Django项目。

image-20210318211155648

image-20210318211504664

image-20210318211652113

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'),
]

image-20210318215135857

比如,来上面的例子,因为接口前缀匹配到<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>static文件开头,并且开设了对应文件的接口,所以才会访问到以上资源。

不信,我们来验证:

3.2 验证:

首先,我们新建static1,static2,static1下面新建a.txt,static2下面新建b.txt。

img

内容如下:

static1下面的a.txt内容
I'm static A
static2下面的b.txt内容
I'm static B

然后启动项目,我们来访问:

image-20210318221827616

image-20210318221925018

还不信的话,我们来修改一下STATIC_URL = '/static/',如图所示:

image-20210318222900928

然后重启项目访问。

image-20210318223241963

补充:

当你在写Django项目的时候,可能回出现后端代码修改了但是前端页面没有变化的情况:

1.你在同一个窗口开了好几个Django项目,一直在跑的其实是第一个Django项目
2.取消网页浏览器缓存

右键--》检查--》shortcuts--》Preferences--》Disable cache...

image-20210318223813577

image-20210318223944306

Edge浏览器:(中文是不是看起来很舒适?)

image-20210318230559360

谷歌浏览器

image-20210318225602215

3.3 动态解析

接着上面的示例,我们再来启动Django项目。

image-20210318233858397

然后我们把令牌改为Shawn,接着又可以了。

image-20210318234414502

image-20210318234512974

这时,产品经理拍着你的肩膀突然来一句说:这样不好,在改一下..

然后你又要改回去,就这样反反复复。

于是就出现了动态解析

动态解析模板语法:
{% 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项目。

image-20210319000041070

image-20210318235950717

我们在来修改令牌,然后随便你怎么改,令牌都可以动态解析到,都可以访问到资源。

image-20210319000354281

image-20210319000517404

image-20210319000735176

image-20210319000846880

还不明白?我们来看一张图,有图有真相:

img

二、request对象方法

1.form表单回顾

  • 作用:将用户输入的数据提交到后端,默认使用的是get请求。

2. form表单三个属性:

2.1 action参数

作用:控制后端提交的路径

三种书写方式:
  1. 不写:默认朝当前页面地址提交数据
  2. 只写后缀:/index/,将当前服务端的ip+port拼接到后缀前面然后访问
  3. 全写: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请求

不写

image-20210319213621088

或者只写后缀:

image-20210319215209310

然后提交数据

image-20210319213830615

然后惊奇的发现我们提交的数据都跑到URLhttp://127.0.0.1:8888/login/?username=123&password=123里面去了,并没有提交到后端。

image-20210319214040537

这是因为action参数默认使用的是get请求,pycharm内打印出如下内容:

image-20210319215851413

2.2 method参数:

作用:指定请求的方式

请求方式:
  1. get请求:数据是直接放在URL后面的, 以"?"分割URL和传输数据,参数之间以"&"相连

    例如:http://127.0.0.1:8888/login/?username=123&password=123

  2. 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>

image-20210319221336935

然后点击提交:

123

结果报错403:请求资源不可用,拒绝访问。

image-20210319224418891

这是因为中间件的作用(暂时不用理解): 需要注释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',
]

image-20210319225411753

注释掉之后,然后我们再来重新提交数据,pycharm打印出如下:

image-20210319224818729

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')

然后在浏览器提交表单

image-20210320003331866

pycharm显示如下,然后就可以获取到当前的请求方法:

image-20210320003730202

通常呢,我们使用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请求返回给浏览器一个登录页面

解决了上面问题,那么我们怎么去获取用户请求数据呢?

首先我们打开断点调试,然后在浏览器提交数据,就可以看到我们刚刚提交的数据了。

image-20210320011910594

任意一个出现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打印如下:

image-20210320130521113

然后我们再来获取用户名,看看它到底是什么数据类型。

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请求返回给浏览器一个登录页面

提交数据后,得到一个字符串的数据类型。

image-20210320131943008

而且,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>

image-20210320132600873

然后前端提交不同的两个用户名,如下:

image-20210320132822897

然后得到列表最后一个元素。

image-20210320133004652

问题又来了,如果获取用户的爱好呢?用户的爱好是可以有多个的那么怎么样去获取呢?

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>

image-20210320133750855

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请求返回给浏览器一个登录页面

前端提交数据,然后后端获取到的数据如下:

image-20210320134557452

image-20210320134942032

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

后端返回数据:

image-20210320140813730

它和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

后端输出数据如下:
image-20210320141859019

接下来我盟再来看看如何获取文件。

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>

image-20210320142709890

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请求返回给浏览器一个登录页面

前端提交数据

image-20210320143027300

后端输出如下:

image-20210320143401099

并没有拿到我们需要的文件对象。

这是因为:针对文件数据,不能使用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请求返回给浏览器一个登录页面

效果如下:

134

注意: 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>

image-20210320144943806

效果展示如下:

image-20210320145539938

版权声明:
作者:淘小欣
链接:https://blog.taoxiaoxin.club/157.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
Django静态文件配置与request对象方法
一、静态文件与配置 在平时,我们之所以能够在浏览器里面输入网址就可拿到对应的资源,是因为开发者开设了该资源对应的访问接口,所以我们能够访问到对应的资……
<<上一篇
下一篇>>