前端 Django 基础知识
Django 虽然也适用于编写 API,但它的主要用途是作为构建完整网站的框架。渲染 HTML 是 Django 的核心功能之一,它使用 Jinja 模板来简化编写灵活、可复用的网页的过程。本文将教你如何使用 Django 创建一个基础网站;我们将创建一个需要登录才能访问的销售仪表盘。本项目将演示使用 Django 进行 Web 开发的一些基本技巧:编写 HTML 视图、使用表单进行身份验证、显示数据库中的数据以及包含静态资源。
本文将采用迭代式方法开发网页。您可以先安装 Python 3 和 Django 2.2 并跟随本文操作,也可以直接跳过这一步,从 GitHub 克隆最终版本。如果您要跟随我一起构建,请先运行 ` django-admin startproject dashboard.`cd dashboard进入目录,然后运行 `.`python manage.py startapp core创建应用程序。请确保在 `settings.py` 文件中添加 ` 'core.apps.CoreConfig'--configuration` 参数INSTALLED_APPS。之后,您就可以通过修改各个文件来跟随本文进行操作了。
无论你是克隆项目还是创建自己的项目,请确保运行命令python manage.py migrate完成python manage.py createsuperuser设置。运行命令python manage.py runserver启动 Django 站点。
我们将首先编写一个简单的视图,用于在浏览器中渲染 HTML。Django 支持基于函数的视图和基于类的视图。在这些示例中,我们将使用基于类的视图,但这完全取决于个人偏好,因为两者提供的功能相同,只是语法不同。当需要支持与单个 URL 的多个交互时,例如需要支持多个 HTTP 方法时,基于类的视图最为有用。
本文我们将练习 Django,而不是 HTML 或 CSS。因此,我们将使用Start Bootstrap 提供的优秀开源模板。该模板将提供本次练习所需的所有 HTML、CSS 和 JS 代码,使我们能够专注于 Django 本身。如果您是从零开始,请下载该模板并将 index.html 和 login.html 文件复制到 /core/templates 目录下。虽然这些模板中的许多功能将仅作为占位符,但它们将帮助我们编写一个交互式网站。
将模板保存到“/core/templates/index.html”后,我们可以在“/core/views.py”中使用以下视图来渲染页面。
from django.shortcuts import render
from django.views import View
class Index(View):
template = 'index.html'
def get(self, request):
return render(request, self.template)
然后,按如下方式将路由添加到“/dashboard/urls.py”中:
from django.contrib import admin
from django.urls import path
from core import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.Index.as_view(), name='index')
]
写好视图后,当我们运行服务器并访问http://127.0.0.1:8000时,我们就可以看到该页面。
目前页面看起来不太美观。幸运的是,模板中包含一些静态资源(CSS、JavaScript 和其他文件),我们可以利用这些资源来改进网站。首先,在“core”目录下创建一个名为“static”的文件夹,然后将“css”、“js”和“vendor”文件夹复制到“static”文件夹中。最后,在 HTML 页面中,需要在头部三个 CSS 导入路径和底部九个 JavaScript 导入路径的路径前添加“/static/”。完成这些步骤后,页面看起来就好多了。
一旦我们能够正确查看页面内容,就会发现这里有很多(虚构的)敏感数据!让我们通过实现登录页面来限制访问权限,这也将是一个很好的 Django 网页表单使用入门教程。
首先,将“login.html”模板复制到与“index.html”相同的“core/templates/”文件夹中。您还需要像之前一样,修改两个CSS导入和三个JavaScript源文件。我们将添加一个路由和一个视图来支持这个新页面。
在 urls.py 文件中:
path('login', views.Login.as_view(), name='login'),
在 views.py 中:
class Login(View):
template = 'login.html'
def get(self, request):
return render(request, self.template)
你会注意到,目前我们的登录页面几乎与首页完全相同。这种情况很快就会改变,以支持实际的登录页面。现在让我们访问登录页面:http://127.0.0.1/login/。尝试使用你之前创建的超级用户凭据登录。
虽然页面看起来很棒,但它目前还没有任何实际功能。为此,我们需要使用表单。幸运的是,Django 提供了一个很棒的默认表单AuthenticationForm,可以接受用户名和密码。我们可以按如下方式将其添加到视图中:
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, authenticate
class Login(View):
template = 'login.html'
def get(self, request):
form = AuthenticationForm()
return render(request, self.template, {'form': form})
def post(self, request):
form = AuthenticationForm(request.POST)
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect('/')
else:
return render(request, self.template, {'form': form})
这还需要对登录页面的 HTML 代码进行一些修改。Django 本身就支持 Jinja 模板。Jinja 模板是 HTML 的一种扩展,它允许你使用双括号来包含数据{{ data }},并使用类似的语法来编写表达式{% expression %}。我们将使用 Jinja 标签将表单嵌入到 HTML 页面中。
<form method="post" action="/login/">
{% csrf_token %}
<div class="form-group">
<div class="form-label-group">
{{ form.username }}
</div>
</div>
<div class="form-group">
<div class="form-label-group">
{{ form.password }}
</div>
</div>
<button class="btn btn-primary btn-block" type="submit">Login</button>
</form>
我们可以稍后引入这段脚本来添加一些 CSS。由于 Jinja 元素是在服务器端渲染成 HTML 的,因此我们可以依赖脚本在客户端运行时 DOM 中已存在的元素 ID。
<script>
document.getElementById("id_username").classList.add("form-control");
document.getElementById("id_password").classList.add("form-control");
document.getElementById("id_username").placeholder = "Username";
document.getElementById("id_password").placeholder = "Password";
document.getElementById("id_username").type = "text";
document.getElementById("id_password").type = "password";
document.getElementById("id_username").required = "required";
document.getElementById("id_password").required = "required";
document.getElementById("id_username").autofocus = "autofocus";
</script>
经过这些更改后,访问登录页面即可登录并查看主仪表盘。然而,眼尖的读者会发现我们尚未对仪表盘实施任何保护措施。实际上,任何人仍然可以访问首页并查看所有敏感信息。因此,我们需要在视图中继承另一个类Index。
from django.contrib.auth.mixins import LoginRequiredMixin
class Index(LoginRequiredMixin, View):
template = 'index.html'
login_url = '/login/'
def get(self, request):
return render(request, self.template)
该类LoginRequiredMixin会阻止除已认证用户以外的任何人访问其保护的页面。如果有人在登录前尝试访问首页,它会方便地将他们重定向到登录页面进行身份验证。
我们使用 Jinja 集成了一个表单;它还可以帮助我们避免重复代码。目前我们只有两个 HTML 页面,但完整实现这个应用会有几十个页面。与其复制粘贴通用元素,我们可以从基础模板继承页眉。
我们首先在“core/templates”目录下创建一个名为“base.html”的新文件。该文件将包含两个页面之间通用的头部信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>{% block title %}{% endblock %}</title>
<!-- Custom fonts for this template-->
<link href="/static/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<!-- Page level plugin CSS-->
<link href="/static/vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet">
{% block links %}
{% endblock %}
</head>
{% block body %}
{% endblock %}
</html>
然后,后续页面可以使用修改后的“index.html”中的以下语法。
{% extends "base.html" %}
{% block title %}Employee Dashboard{% endblock %}
{% block links %}
<!-- Custom styles for this template-->
<link href="/static/css/sb-admin.css" rel="stylesheet">
{% endblock %}
{% block body %}
<!--html goes here-->
{% endblock %}
首页上还有一处地方可以应用 Jinja 模板。目前,表格中的所有数据都硬编码在 HTML 代码中,这意味着每次数据更改时都需要修改网页本身。我们可以将数据存储在数据库中,然后传递给视图。这样一来,使用当前数据,我们就能节省近 500 行手动编写的 HTML 代码。
首先,我们需要一个模型来表示数据库中的员工。在“core/models.py”文件中,我们按如下方式定义员工。
from django.db import models
class Employee(models.Model):
name = models.CharField(max_length=150)
position = models.CharField(max_length=150)
office = models.CharField(max_length=150)
age = models.PositiveIntegerField()
start_date = models.DateField()
salary = models.PositiveIntegerField()
def __str__(self):
return self.name
请确保在“core/admin.py”中注册模型。
from django.contrib import admin
from .models import Employee
class EmployeeAdmin(admin.ModelAdmin):
list_display = [f.name for f in Employee._meta.fields]
admin.site.register(Employee, EmployeeAdmin)
模型编写并注册完成后,我们就可以创建并运行迁移(退出服务器,,,python manage.py makemigrations)python manage.py migrate。python manage.py runserver导航至 /admin 并点击 employees 表。点击右上角的“添加员工”,然后在表单中输入所需的数据。
重复此操作几次,直到创建一个小型虚拟公司。然后,返回到“views.py”文件,修改代码Index,将员工数据库作为查询集传递到HTML文件中。
def get(self, request):
employees = Employee.objects.all()
return render(request, self.template, {'employees': employees})
最后,删除“index.html”中的整个虚假表格,并将其替换为我们输入到数据库中的数据的 for 循环。
<tbody>
{% for employee in employees %}
<tr>
<td>{{ employee.name }}</td>
<td>{{ employee.position }}</td>
<td>{{ employee.office }}</td>
<td>{{ employee.age }}</td>
<td>{{ employee.start_date }}</td>
<td>${{ employee.salary }}</td>
</tr>
{% endfor %}
</tbody>
Django 通过渲染数据库来创建索引,而不是简单地返回填充数据。所有搜索和排序功能仍然像以前一样正常工作,唯一的区别是 HTML 是由服务器端根据数据库生成的,而不是硬编码的。
我们已经了解了使用 Django 和 Jinja 创建网页的几种强大模式。使用模板和扩展可以让我们在页面之间复用通用代码。表单允许我们安全地收集和传输用户数据(当网站通过 HTTPS 提供服务时)。我们可以使用服务器端渲染将数据包含在 HTML 中并将其发送给客户端。这些基本模式是使用 Django 创建各种网页的必备技能。
这是由 Philip Kiely 撰写的mkdev 文章。您可以聘请我们的 Python 导师自学 Python 和 Django。
文章来源:https://dev.to/mkdev/fundamentals-of-front-end-django-b2k




