外观
FBV视图——基于函数的视图
- 定义路由。在article/urls.py文件中定义路由,代码如下:
from django import path
from . import views
urlpatterns = [
path('', views.article_list),
path('<int:year>/', views.year_archives),
path('<int:year>/<int:month>/', views.month_archives),
path('<int:year>/<int:month>/<slug:slug>/', views.article_details),
path('current', view.get_current_datetime)
]- 创建视图函数。在article/views.py文件中创建一个名为get_current_datetime()视图函数,代码如下:
from django import HttpResponse
from datetime import datetime
def get_current_datetime(request):
today =datetime.today()
formatted_today = today.strftime('%Y-%m-%d')
html = f'<html><body>今天是{formatted_today}</body></html>'
return HttpResponse(html)上方的代码中定义了一个函数,返回了HttpResponse对象。每个视图函数都需要有一个HttpRequest对象作为参数,用来接收客户端传递过来的参数,并且必须返回一个HttpResponse对象,作为响应返回给客户端。
- CBV视图——基于类的视图
首先定义一个类,它继承自View视图类,然后在里面定义get()和post()方法,在接收到对应的请求时自动调用对应的方法。如:
from django.view import View
from django.http import HttpResponse
class ArticleView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('GET请求')
def post(self, request, *args, **kwargs):
return HttpResponse('POST请求')Django模板
Django使用render()函数渲染模板。之前的代码都是使用HttpResponse创建响应,修改这部分文件,代码如下:
from django.shortcuts import render
from article.models import Article, User
def article_list(request):
articles = Article.object.all()
return render(request, 'article.html', {'articles': articles})上述代码中,从Articles表中获取全部数据,然后使用render()函数渲染模板,设置模板文件为article.html,并向模板内存入参数。
随后在后台中添加内容。由于Article表还未添加数据,所以我们先登录后台,添加Article模型数据,如下图。

随后创建模板文件。Django默认的模板文件夹为article/templates。在对应位置创建文件夹,并在里面创建article_list.html和base.html文件。base.html为基模板,在这里面可以引入相同的信息和导航栏等公共元素。base.html的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}">
<script src="{% static 'js/jquery.js' %}"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
</head>
<body class="container">
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<!--省略导航栏代码-->
</nav>
{% block content %}{% endblock %}
</body>
</html>在base.html中使用了{% block xxx %}作为占位符,使用{% load static %}导入静态文件路径,即article/static路径。接下来,在article_list.html中编写以下代码:
{% extends "base.html" %}
{% block title %}文章列表{% endblock %}
{% block content %}
<div style="margin-top:20px">
<h3>文章列表</h3>
<table class="table table-bordered ">
<thead>
<tr>
<th>文章ID</th>
<th>作者</th>
<th>标题</th>
<th>发布时间</th>
</tr>
</thead>
<tbody>
{% for article in articles %}
<tr>
<td>{{ article.id }}</td>
<td>{{ article.user.username }}</td>
<td>{{ article.title }}</td>
<td>{{ article.publish_date | date:'Y-m-d' }}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}Django模板引擎使用“{% %}”来描述Python语句,以区别于html标签。使用“{{ }}”来描述变量。上面的代码及说明如下表索所示。
| 标签 | 说明 |
|---|---|
{% extends 'base.html'%} | 扩展一个基模板 |
{%block title%} | 指定父模板中的一段代码块,此处为title,在父模板中定义title,可以在子模块中重写该代码。block标签必须是封闭的,要由{% end block %}结尾 |
{{ article.title }} | 获取变量的值 |
{% for element in lst%}<br />{% endfor %} | 和Python中的for循环比较类似 |
此外,“|”为过滤器。Django的过滤器非常实用,可对返回的变量做进一步处理。常用的过滤器如下:
| 过滤器 | 说明 |
|---|---|
{{value|default:"nothing"}} | 用来指定默认值 |
{{value|length}} | 用来计算返回的列表或者字符串长度 |
{{value|lower}} | 用来将返回的数据变为小写字母 |
{{value|date}} | 用来将日期格式转换为字符串格式 |
{{value|safe}} | 不使用转义 |
{{value|filesizeformat}} | 用于使文件大小变得易读,如15KB |
{{value|truncatewords:30}} | 对返回的字符加以截取,多用于显示文章摘要,此处为30个字符 |
表单
Django提供了一个表单类功能,可以将Python字段转换为HTML的表单。首先在blog/article下创建一个form.py文件,代码如下:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(
label='姓名',
required=True,
min_length=3,
max_length=10,
widget=forms.TextInput(attrs={'class': 'form-control'}),
error_messages={
'required': '用户名必须填写',
'min-length': '长度不能少于3个字符',
'max-length': '长度不能多于10个字符'
}
)
email = forms.EmailField(
label='邮箱',
required=True,
max_length=50,
widget=forms.TextInput(attrs={'class': 'form-control'}),
error_messages={
'required': '邮箱必须填写',
'max-length': '长度不能多于50个字符'
}
)上述代码创建了一个LoginForm类,它继承自表单类Form类;它里面有两个字段:用户名username和邮箱email,分别对应数据库中的用户名和邮箱字段。由于这两个字段都为字符串型数据,因此都用forms.CharField类实例化。此外,forms类中还有其他的字段类型属性,如IntegerField、FloatField、DateFIeld等。在forms.FIeld实例化时,可以设置验证规则,如required用于设置该字段是否必须被填写,min_length用于设定最小长度等。此外,还可以widget参数来设定表单中字段的样式。
LoginForm类将呈现如下的代码:
<div class='form-group'>
<label>姓名:</label>
<input type='text' name='username' class='form-control' maxlength='10' minlength='3' required id='id_username'>
</div>
<div class='form-group'>
<label>邮箱:</label>
<input type='text' name='email' class='form-control' maxlength='50' required id='id_email'>
</div>接下来创建路由。在article/urls.py中配置路由:
urlpatterns = [
path('login', views.LoginFormView.as_view())
]接下来创建FCV,并在类中设置get()和post()方法:
class LoginFormView(View):
def get(self, request, *args, **kwargs):
return render(request, 'login.html', {'form': LoginForm()})
def post(self, request, *args, **kwargs):
# 将请求数据传入到form实例中
form = LoginForm(request.POST)
# 判断是否为有效表单
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
return HttpResponse(f'username={username},email={email}')
else:
return render(request, 'login.html', {'form': form})上述代码中,定义了get()方法和post()方法,用于处理GET请求和POST请求。在提交表单时,会调用post()方法。
最后就是创建login.html模板文件。
{% extends 'base.html' %}
{% block titie %}登录页面
{% endblock %}
{% block content %}
<style>
.errorlist {
color: red;
}
</style>
<div class="container">
<form action="" method="post">
{% csrf_token %}
<div class='form-group'>
<label>{{ form.username.label }}</label>
{{ form.username }}
{{ form.username.errors }}
</div>
<div class='form-group'>
<label>{{ form.email.label }}</label>
{{ form.email }}
{{ form.email.errors }}
</div>
<button type="submit">提交</button>
</form>
</div>
{% endblock %}在模板文件中,使用form.field_name来获取对应的字段信息,并通过form.field_name.errors来获取字段验证失败时的提示信息。此外,使用模板标签{% csrf_token %}来验证表单的真伪性。
Session会话
由于HTTP是无状态的,因此网页一般都会把信息存放到Cookie中。Django提供了一个Session框架,并且提供了多种存储这种数据的方法。
- 保存到数据库。
- 保存在缓存中。
- 保存到文件。
- 保存到Cookie。
Django支持匿名会话,会话允许在每个站点访问者的基础上访问任何数据。它将数据存储到服务器中,并抽象发送和接收Cookie。