本文为 Django 学习总结,讲解 Django 的高级用法
所有的代码见【Django】系列。
包括 css、js、图片、Json 文件、字体文件等。静态文件一般放在 project 目录下的 static 文件夹下,与 templates 同级。在 static 文件夹下还要创建每个应用对应的文件夹,在对应文件夹下还要创建存放不同类型文件的文件夹。看起来可能有点绕,可以参考下图:
现在我们想将模板中的字体设置为红色的,可以直接在 style.css 中配置:
h1{
color:red;
}
然后在 settings.py 中配置静态文件夹路径,在 settings.py 的最后一行加入:
# 设置用来访问这个文件夹的URL地址
STATIC_URL = '/static/'
# 把项目中的static文件夹设置为静态文件夹
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static') # static对应前面创建的目录
]
使用下面的代码在 html 中引入 css 样式:
<head>
<meta charset="UTF-8">
<title>首页title>
<link rel="stylesheet" type="text/css" href="/static/myApp/css/style.css"/>
head>
<body>
<h1>Mike is a good manh1>
body>
得到结果:
想要使用 jquery-3.1.1.min.js 和 sunck.js 文件。其中 jquery-3.5.1.min.js 在 jquery 官网直接下载,并放到 js 目录下。sunck.js 中添加:
// sunck.js
console.log("good man")
需要在 link
后添加下面的代码。:
<script type="text/javascript"
src="/static/myApp/js/jquery-3.5.1.min.js">script>
<script type="text/javascript"
src="/static/myApp/js/sunck.js">script>
刷新后查看 Consule,得到值:
再显示一张图片,在 h1
后添加下面的代码:
<img src="/static/myApp/img/IMG_0468.PNG"/>
但是,如果文件名发生了变化,html 文件中的所有路径都需要变化,工作量很大,我们可以采取类似反向解析的方法,给路径起“别名”。
首先在 html 文件第一行引入静态文件:
{% load static from staticfiles %}
图片就可以用下面的方式添加:
{% load static %} # django3中使用。django2中使用load static from staticfiles
得到结果:
将这些硬链接改为“别名”,如果我们修改了静态文件的名称,也无需修改 html 中的路径。
一个轻量级、底层的插件,可以介入 Django 的请求和相应,本质为一个 Python 类。settings.py 中的 MIDDLEWARE
即为系统提供的中间件
__init__
:
不需要传参数,服务器响应第一个请求时自动调用,用于确认是否启用该中间件。
process_request(self, request)
:
在执行视图(分配 url 匹配视图)之前被调用,每个请求都会调用,返回 None 或 HttpResponse 对象
process_view(self, request, view_func, view_args, view_kwargs)
:
调用视图之前执行,每个请求都会调用,返回 None 或 HttpResponse 对象
process_template_response(self, request, response)
:
在视图刚好执行完后调用,每个请求都会调用,返回 None 或 HttpResponse 对象
process_response(self, request, response)
:
所有响应返回浏览器之前调用,每个请求都会调用,返回 HttpResponse 对象
process_exception(self, request, request, exception)
:
当视图抛出异常时调用,返回 HttpResponse 对象
总结为下图:
我们现在想要在某个过程中拿到中间件的执行结果。首先自定义中间件,在 templates 同级目录下创建 middleware 文件夹,创建该应用对应的文件夹,并创建 mymiddle.py 来自定义中间件:
在 myMiddle.py 中添加下面的代码:
from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
def process_request(self, request):
print("get参数为:", request.GET.get("a"))
需要配置 settings.py 文件,添加路径:
'middleware.myApp.myMiddle.MyMiddle',
在浏览器中输入 127.0.0.1:8000/?a=1
,打印出结果:
文件上传时,文件数据存储在 request.FILES 属性中。一般将上传图片存储在 static 目录下创建的 upfile 目录中,然后配置 settings.py 文件,在最后添加:
# 上传文件目录
MEDIA_ROOT=os.path.join(BASE_DIR, r'static\upfile')
此时的服务器为 project 文件夹。新建上传文件的模板:
<body>
<form method="post" action="/savefile/" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="file"/>
<input type="submit" value="上传"/>
form>
body>
配置 url 和视图将页面展示出来:
定义的视图文件如下:
def upfile(request):
return render(request, 'myApp/upfile.html')
import os
from django.conf import settings
def savefile(request):
if request.method == "POST": # 上传文件必须是POST请求
f = request.FILES["file"] # 相当于文件描述符
# 合成文件在服务器端的路径
filePath = os.path.join(settings.MEDIA_ROOT, f.name)
with open(filePath, 'wb') as fp: # wb表示图片文件,普通文件为w
for info in f.chunks():
fp.write(info)
return HttpResponse("上传成功")
else:
return HttpResponse("上传失败")
成功上传到 upfile 文件夹下:
格式为 Paginator(列表, 整数)
,返回分页对象。
count
:得到对象总数num_pages
:页面总数page_range
:页码列表,如 [1,2,3,4,5]
,页码从 1 开始。page(num)
,获得 Page 对象,如果提供的页码不存在会抛出 InvalidPage
异常InvalidPage
:当向 page()
传递的是一个无效的页码时抛出PageNotAnInteger
:当向 page()
传递的不是一个整数时抛出EmptyPage
:当向 page()
传递一个有效值,但该页面没有数据时抛出Paginator 对象的 page()
方法返回得到的对象,无需手动创建
object_list
:当前页上所有数据(对象)的列表number
:当前页的页码值paginator
:当前 page
关联的 paginator
对象has_next()
:判断是否有下一页,如果有返回 True
has_previous()
:判断是否有上一页,如果有返回 True
has_other_pages()
:判断是否有上一页或下一页,如果有返回 True
next_page_numbers()
:返回下一页的页码,如果不存在抛出 InvalidPage
异常pervious_page_number()
:返回上一页的页码,如果不存在抛出 InvalidPage
异常len()
:返回当前页的数据(对象)个数下面用一个学生列表分页的实例演示上述的方法。
首先配置 url:
re_path(r'^studentpage/(\d+)/$', views.studentpage),
定义视图函数:
from .models import Students
from django.core.paginator import Paginator
def studentpage(request, pageid):
# 所有学生列表
allList = Students.objects.all()
paginator = Paginator(allList, 2)
page = paginator.page(pageid)
return render(request, 'myApp/studentpage.html', {"students":page})
渲染对应的 studentpage 模板:
<body>
<ul>
{% for stu in students %}
<li>
{{stu.sname}}--{{stu.sgrade}}
li>
{% endfor %}
ul>
body>
浏览器中输入第一页的 url 查看第一页的数据:
可以在此基础上添加按钮进行页面展示。
渲染模板中添加:
<ul>
{% for index in students.paginator.page_range %}
{% if index == students.number %}
<li>{{index}}li>
{% else %}
<li>
<a href="/studentpage/{{index}}/">{{index}}a>
li>
{% endif %}
{% endfor %}
ul>
点击页面按钮,跳转页面并将当前页的页码置为无法点击:
需要动态生成,请求 JSON 数据。我们通过点击按钮显示学生列表,获取 JSON 数据。
首先新建 ajaxstudents.html,添加下面的内容:
<head>
<meta charset="UTF-8">
<title>Titletitle>
<script type="text/javascript" src="/static/myApp/js/jquery-3.1.1.min.js">script>
head>
<body>
<h1>学生信息列表h1>
<button id="btn">显示学生信息button>
<script type="text/javascript" src="/static/myApp/js/sunck.js">script>
body>
配置 url 后得到页面显示为:
然后在 sunck.js 中添加下面的内容,获取 JSON 数据:
$(document).ready(function() {
document.getElementById("btn").onclick = function(){
$.ajax({
type:"get",
url:"/studentsinfo/",
dataType:"json",
success:function(data, status){
console.log(data)
}
})
}
})
视图中获取学生列表,并传递 JSON 数据:
from django.http import JsonResponse
def studentsinfo(request):
stus = Students.objects.all()
list = []
for stu in stus:
list.append([stu.sname, stu.sage])
return JsonResponse({"data": list})
成功在 Console 中得到了学生列表的 JSON 数据:
然后需要将学生列表作为标签插入到模板中,修改 sunck.js 中的 success:function
为:
success:function(data, status){
console.log(data)
var d = data["data"]
for(var i = 0; i < d.length; i++){
document.write(''
+d[i][0]+'')
}
}
点击按钮,显示学生列表:
直接使用命令 pip install django-tinymce
进行安装
我们平时写博客时,会有一些加粗、斜体的文字编辑功能,这就是富文本。
首先配置 settings.py 文件,在 INSTALLED_APPS
中添加:
INSTALLED_APPS = [
……
'tinymce'
]
并在文件最后添加下面的代码。advanced 主题可能会出问题,在没有默认配置时 tinymce 会自动确定配置,直接删除即可。
# 富文本
TINYMCE_DEFAULT_CONFIG = {
# 'theme': 'advanced', # 配置模式
'width': 600,
'height': 400,
}
在 models.py 中再创建一个模型:
from tinymce.models import HTMLField
class Text(models.Model):
str = HTMLField() # 大文本类型
重新迁移,迁移步骤见【跑通 Django】。
然后注册 admin,相关讲解见【Django 站点管理】。在 admin.py 中添加:
from .models import Text
admin.site.register(Text)
使用命令 python manage.py createsuperuser
创建管理员用户。进入 admin 界面,在 Text 中点击 Add 添加,可以看到富文本:
首先写一个 edit.html 模板:
<head>
<meta charset="UTF-8">
<title>富文本title>
<script type="text/javascript" src="/static/tiny_mce/tiny_mce.js">script>
<script type="ext/javascript">
tinyMCE.init({
'mode': 'textarea',
'theme': 'advanced',
'width': 800,
'height': 600,
})
script>
head>
<body>
<form action="/saveedit/" method="post">
<textarea name="str">Mike is a good mantextarea>
<input type="submit" value="提交"/>
form>
body>
在 saveedit 中定义视图,对提交的博客内容进行保存即可。