【玩转全栈】----Django模板语法、请求与响应

目录

一、引言

二、模板语法

三、传参

1、视图函数到模板文件

2、模板文件到视图函数

四、引入静态文件

五、请求与响应

1、请求

2、响应

六、综合小案例

1、源码展示

2、注意事项以及部分解释

3、展示


一、引言

像之前那个页面,太过简陋,而且一个完整的页面,也不可能只用HttpResponse返回文本,这就可以用django的模板语法,模板语法相当于将前后端分离了,前端专写页面,写成一个html文件,然后后端在视图函数中可以通过渲染(render)将前端的html文件渲染为HTTP响应。

app文件目录如下:

app01

│ ├─migrations

│ │ └─pycache

│ ├─static

│ │ ├─css

│ │ ├─img

│ │ ├─js

│ │ └─plugins

│ ├─templates

│ └─pycache

└─myproject

└─pycache

static文件夹用来存放静态文件,包括样式css,图片img,网页的js和插件plugins

而templayes是用来存放模板的,一些编写的html文件通常存放于此

二、模板语法

模板语法如何实现呢,其实很简单,首先得创建一个html文件,对网页进行设计,然后在视图函数中进行返回即可。

新建html文件:

此文件即可和前端联系起来,可以在这儿简单写个页面

html 复制代码
<h2>展示</h2>
复制代码
配置路径
python 复制代码
path("show/", views.show_1),

在视图函数中返回该页面

python 复制代码
def show_1(request):
    return render(request, 'show_1.html')

返回页面是用的render,第二个参数就是要显示的html文件

启动项目后显示了"展示",当然,有前端基础的同学就可以尽情发挥,设计一个更加完善的页面

|----------|------------------|--------------------------|-------------------------------|
| 基本功能 | 返回指定内容作为 HTTP 响应 | 渲染模板文件并返回包含动态内容的 HTTP 响应 | 返回一个 HTTP 重定向响应,将用户跳转到另一个 URL |

|----------|-----------------------|-----------------------|-----------------------|
| 常用场景 | 用于返回简单的字符串、HTML 或其他内容 | 用于返回包含动态页面的完整 HTML 响应 | 用于重定向用户到其他页面(如成功后的跳转) |

|------------|----------------------|--------------|--------------------|
| 返回内容类型 | 文本、HTML、JSON 或其他任意内容 | 渲染后的 HTML 内容 | 重定向响应,浏览器跳转到目标 URL |

|----------|-------------------|----------------------------|--------------------|
| 函数参数 | 内容(如字符串或 HTML 代码) | request、模板文件路径、上下文数据(字典) | URL 名称、URL 路径或视图名称 |

|----------|-------------------|---------------------------------|---------------------------|
| 返回对象 | HttpResponse 对象 | HttpResponse 对象(经过模板渲染的 HTML) | HttpResponseRedirect 对象 |

三、传参

模板文件和视图函数可以进行相互传参 ,主要通过 上下文数据(Context) 进行传递。以下是详细说明:

1、视图函数到模板文件

视图函数传参到模板文件只需添加一个context参数即可,并返回,context数据可包括一般的数据类型(字符串、数字、布尔值等),也可传一些储存数据的结构,比如列表、字典等等.

记得在render渲染器中加入context参数

python 复制代码
def show_1(request):
    list = [1,2,3,4,5]
    dict = {'name':'zhang','age':23,'from':'China'}
    context = {
        "name":"小谭",
        "age":18,
        "ishandsome":True,
        "list":list,
        "dict":dict
    }
    return render(request, 'show_1.html', context)

在模板文件中接收到的参数,可用{ { }}显示到页面上,字典用key值索引,列表用整数索引取值,对于列表和字典的循环索引,可以使用模板文件中的for循环。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>展示</h2>
<h2>姓名:{
  {name}},年龄:{
  {age}},帅不帅?{
  {ishandsome}}的</h2>
<div>
  {% for item in list %}
    <h1>{
  {item}}</h1>
  {% endfor %}
</div>

<ul>
    {% for k,v in dict.items %}
    <li>{
  {k}}={
  {v}}</li>
    {% endfor %}
</ul>
</body>
</html>

页面结果:

2、模板文件到视图函数

在定义视图函数时的参数requests其实是一个对象,内容包括用户发送网络请求后的一些信息,比如用户填写的表单等等。

这里我们新配置一个登录的url进行演示

python 复制代码
#添加路径
path("login/", views.login),

#定义视图函数
def login(request):
    
    return render(request, 'login.html')

写一个简单的表单

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户登录</h1>
<form action="/login/" method="post">
    #{% csrf_token %}
    <input type="text" name="user" placeholder="用户名">
    <input type="password" name="pwd" placeholder="密码">
    <input type="submit" value="提交"/>
</form>
</body>
</html>

启动项目,随便输入一点数据

提交后会出现如下错误:

这是django独有的安全检测,解决方法也很简单,只需在代码块中添加这个:

html 复制代码
{% csrf_token %}

加了之后右键检查网页源代码(或按F12),发现表单中多了一长串value,这一串码是django内部用来校验是否是正常我的网页发过来的,django会自动读取,这样就可以跳过django的安全检测。

在视图函数中编写代码,以接收并测试传送数据,因为是表单提交,所以是POST请求

html 复制代码
def login(request):
    if request.method == 'POST':
        print(request.POST)
    return render(request, 'login.html')

在网页中输入数据并提交,发现控制台会打印出刚才表单输入的数据,这其实就是requests请求的参数。

还可以通过取值获取到这些具体的参数

python 复制代码
username = request.POST['user']
password = request.POST['pwd']

四、引入静态文件

之前讲过一般只需要创建一个应用(app),但如果创建了多个应用,不可能每个应用创建一个templates,一般是整个Django项目共用一个templates,所以会在settings文件中进行配置,以让所有应用能共用templates。

在settings文件的大概58行加入:

python 复制代码
"DIRS": [os.path.join(BASE_DIR, "templates")],

别忘了在前面引入os库!!

os.path.join(BASE_DIR, "templates") 的作用是将 BASE_DIR(项目的根目录)与 templates 子目录拼接成一个绝对路径,告诉 Django 从这个文件夹中寻找模板文件。

静态文件的介绍和一般存放位置前面已经讲了,现在来讲讲静态文件在页面中的引用

前端写好的文件和一些img之类的,可以应用到模板中。

如果是像我之前那样在控制台输入指令新建的Django文件,则用不了{% static %} 标签。但可以用文件的相对路径。

html 复制代码
<img src="/static/img/picture_1.jpg" alt="">
<link rel="stylesheet" href="static/css/styles.css">
<script src="/static/js/jquery-3.6.0.min.js"></script>
<script src="/static/plugins/bootstrap-3.4.1/js/bootstrap.js"></script>

若是在Pycharm中创建的Django,可以使用{% static %} 标签引入静态文件

先在模板文件的顶部加入{% load static %}

引入 CSS 文件

html 复制代码
<link rel="stylesheet" href="{% static 'css/styles.css' %}">

引入 JS 文件

html 复制代码
<script src="{% static 'js/scripts.js' %}"></script>

引入图片

html 复制代码
<img src="{% static 'img/logo.png' %}" alt="Logo">

引入其他静态资源

对于插件或 TypeScript 文件:

html 复制代码
<script src="{% static 'plugins/plugin.js' %}"></script> 
<script src="{% static 'ts/script.ts' %}"></script>

但是用这个语法,要用Pycharm创建Django项目,而且需要用专业版的Pycharm,不然会有报错,大家有专业版的可以用这种语法,社区版的就还是用上面的文件的相对路径引入即可。

五、请求与响应

1、请求

用户发送请求一般分为GET 请求和POST 请求,GET 和 POST 是 HTTP 的两种请求方法,GET 用于从服务器获取数据,参数通过 URL 传递,易被缓存,适合传递少量、非敏感数据;POST 用于向服务器提交数据,参数通过请求体传递,适合提交表单或大数据,且更安全。GET 请求参数可见,长度有限且幂等;POST 参数不可见,无长度限制,通常会修改服务器状态,不具幂等性。GET 常用于查询操作,POST 常用于提交数据或更新操作。

查询请求的方式:

html 复制代码
requests.method

就对于前面写的表单,在控制台打印请求,就是POST请求

获取请求的方式:

python 复制代码
request.POST

结果是一个对象,用来获取客户端通过 POST 请求 提交的数据。它是一个类似字典的对象,包含了所有通过 POST 方法提交的表单数据(通常是键值对的形式)。

python 复制代码
request.GET

是 Django 中用于获取通过 GET 请求 提交的查询参数的一个对象。它是一个类似字典的对象,包含了客户端通过 URL 查询字符串传递的所有参数。

2、响应

像上面介绍的render,还有之前的HttpResponse,还有一个redirect重定向,都是经常用到的视图响应函数 的工具

redirect重定向是用户发送请求后,直接跳转到另外的网址,比如百度官网之类的,编写方式如下:

python 复制代码
return redirect('https://blog.csdn.net/2403_83182682?type=blog')

第一个参数就是要跳转的网址

三个响应函数的区别如下:

|----------|------------------|--------------------------|-------------------------------|
| 基本功能 | 返回指定内容作为 HTTP 响应 | 渲染模板文件并返回包含动态内容的 HTTP 响应 | 返回一个 HTTP 重定向响应,将用户跳转到另一个 URL |

|----------|-----------------------|-----------------------|-----------------------|
| 常用场景 | 用于返回简单的字符串、HTML 或其他内容 | 用于返回包含动态页面的完整 HTML 响应 | 用于重定向用户到其他页面(如成功后的跳转) |

|------------|----------------------|--------------|--------------------|
| 返回内容类型 | 文本、HTML、JSON 或其他任意内容 | 渲染后的 HTML 内容 | 重定向响应,浏览器跳转到目标 URL |

|----------|-------------------|----------------------------|--------------------|
| 函数参数 | 内容(如字符串或 HTML 代码) | request、模板文件路径、上下文数据(字典) | URL 名称、URL 路径或视图名称 |

|----------|-------------------|---------------------------------|---------------------------|
| 返回对象 | HttpResponse 对象 | HttpResponse 对象(经过模板渲染的 HTML) | HttpResponseRedirect 对象 |

|------------|----------------------------------------|-----------------------------------------|---------------------------------|
| 适用场景示例 | 返回简单消息或 API 响应:HttpResponse("Hello") | 返回渲染的页面:render(request, "index.html") | 用户登录后跳转:redirect("dashboard") |

六、综合小案例

经过前面的学习,详细您对Django以及有了一定的了解,下面进行一个小案例。

需求是定义一个登录页面,用户名或密码输出,会提示,正确则跳转到一个url,内容是所爬取的豆瓣电影排行前25。

可以就在之前的login上修改修改就行

1、源码展示

视图函数:

python 复制代码
def login(request):
    # 豆瓣电影前25排行
    headers = {'user-agent':
                   'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) '
                   'Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0'}
    response = requests.get("https://movie.douban.com/top250", timeout=10, headers=headers)
    response = response.text
    resp = re.findall(r'<span class="title">(?!.*&nbsp;)(?P<name>.*?)</span>', response)
    if request.method == 'POST':
        print(request.method)
        print(request.POST)
        username = request.POST['user']
        password = request.POST['pwd']
        context= {
            'name':username,
            'password':password,
            'resp':resp
        }
        if username == 'edward' and password == '1234':
            return render(request, 'douban.html',context)
        else:
            # error_msg 登录失败返回信息
            return render(request, "login.html", {"error_msg": "用户名或密码错误"})

    return render(request, "login.html")

登录页面:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            flex-direction: column;
            text-align: center;
        }
        /* 调整图片大小 */
        img {
            width: 200px;
            height: auto;

        }
        input[type="text"], input[type="password"], input[type="submit"] {
            font-size: 18px;
            padding: 10px;
            margin: 10px 0;
            width: 25%;
            box-sizing: border-box;
        }
        input[type="submit"] {
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
        }
        input[type="submit"]:hover {
            background-color: #45a049;
        }
        span {
            font-size: 8px;
            color: red;
        }
    </style>
</head>
<body>
<h1>用户登录</h1>
<form action="/login/" method="post">
    {% csrf_token %}
    <input type="text" name="user" placeholder="用户名">
    <input type="password" name="pwd" placeholder="密码">
    <input type="submit" value="提交"/>
    <!--只有当error_msg存在时才显示错误信息-->
    {% if error_msg %}
        <span style="color: red">{
  { error_msg }}</span>
    {% endif %}
</form>
<img src="/static/img/picture_1.jpg" alt="">

</body>
</html>

显示电影排行页面:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>豆瓣Top25</h1>
<div>豆瓣电影前25榜单:</div>
<ul>
    {% for item in resp%}
        <li>{
  {item}}</li>
    {% endfor %}
</ul>
<div>{
  {response}}</div>
</body>
</html>

2、注意事项以及部分解释

注意视图函数用了requests请求以及re解析,需在前面引入

python 复制代码
import re
import requests

下面这段是关于网络爬虫的,有基础的可以看看,没基础的直接复制就行。

python 复制代码
headers = {'user-agent':
                   'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) '
                   'Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0'}
    response = requests.get("https://movie.douban.com/top250", timeout=10, headers=headers)
    response = response.text
    resp = re.findall(r'<span class="title">(?!.*&nbsp;)(?P<name>.*?)</span>', response)

这里的用户名和密码是自己设置的,一般来说,用户名和密码是不会出现在代码中的,容易泄露,可以存放于数据库中,但我图方便就先这样了,后面再出一个完整的Django和Mysql连接的博客。

python 复制代码
if username == 'edward' and password == '1234':
            return render(request, 'douban.html',context)

html页面做得比较简洁,有前端基础的同学可以试着改改,使页面更加美观。

3、展示

初始界面:

用户名或密码输入错误,提示错误:

成功登录,显示排行榜:

感谢大家的三连!!!我会尽快更新的

相关推荐
weixin_BYSJ19872 小时前
django农作物批发交易系统--附源码24008
java·javascript·spring boot·python·django·flask·php
硕博计算机毕设指导2 小时前
【大数据毕设全套源码+文档】Django基于大数据技术的智慧居家养老服务平的设计与实现(丰富项目+远程调试+讲解+定制)
大数据·python·信息可视化·django·毕业设计·课程设计
B站计算机毕业设计超人2 小时前
计算机毕业设计Python+Django考研院校推荐系统 考研分数线预测系统 大数据毕业设计 (代码+LW文档+PPT+讲解视频)
大数据·人工智能·hive·python·django·毕业设计·课程设计
补三补四2 小时前
Django与模板
数据库·python·django·sqlite
程序辅导开发2 小时前
django体育用品数据分析系统 毕业设计---附源码28946
数据库·vue.js·python·mysql·django·sqlite
工业互联网专业2 小时前
基于Django的智能水果销售系统设计
数据库·vue.js·django·毕业设计·源码·课程设计
猫头鹰源码(同名B站)2 小时前
基于django+vue的时尚穿搭社区(商城)(前后端分离)
前端·javascript·vue.js·后端·python·django
QQ_19632884752 小时前
python高校失物招领平台38tp1_django Flask vue pycharm项目
python·django·flask
N***77882 小时前
【玩转全栈】----Django模板语法、请求与响应
数据库·python·django