静态文件

css、js、图片、json文件、字体文件等

static目录是创建在最外层的project下的,也就是和templates是同级的

配置settings.py:

STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
{% load static from staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" type="text/css" href="/static/myapp/css/style.css"/>
<script type="text/javascript"
src="/static/myapp/js/sunck.js"></script>

</head>
<body>
<h1>sunck is a good man</h1>
<img src="/static/myapp/img/56464486_p0.png"/>
<img src="{% static 'myapp/img/56464486_p0.png' %}"> //static拿到的是STATIC_URL
</body>
</html>

中间件

概述:一个轻量级、底层的插件,可以介入Django的请求和响应

方法:

__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对象;使用render

process_reponse(self,request,response):所有响应返回浏览器前调用,每个请求都会调用,返回HttpREsponse对象

process_exception(self,request,exception):当视图抛出异常时调用,返回HttpREsponse对象

自定义中间件:在工程目录project下创建middleware目录,再创建myapp目录

#settings.py MIDDLEMARE中添加我们定义的中间件
MIDDLEWARE = [
...
'middleware.myapp.mymiddle.MyMiddle'
]
#mymiddle.py
from django.utils.deprecation import MiddlewareMixin

class MyMiddle(MiddlewareMixin):
def process_request(self,request):
print("get参数为:",request.GET.get("a"))

上传图片

概述:文件上传时,文件数据存储在request.FILES属性中

存储路径:在static目录下创建upfile目录

注意:form表单要上爱吃文件需要加上enctype=”multipart/form-data”;上传文件必须是POST请求

#配置settings.py 上传文件目录
MEDIA_ROOT=os.path.join(BASE_DIR,r'static\upfile')
#upfile.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" action="/savefile/"
enctype="multipart/form-data">
{%csrf_token%}
<input type="file" name="file1">
<input type="submit" value="上传">
</form>
</body>
</html>
#views.py
def upfile(request):
return render(request,'myapp/upfile.html')

def savefile(request):
if request.method=="POST":
f=request.FILES["file1"]
#文件在服务器端的路径
filePath=os.path.join(settings.MEDIA_ROOT,f.name)
with open(filePath,'wb') as fp:
for info in f.chunks():
#如果文件太大
fp.write(info)
return HttpResponse("上传成功")

else:
return HttpResponse("上传失败")

分页

Paginator对象:

创建对象:

格式:Paginator(列表,每页个数) 返回值:返回分页对象

属性:

count:对象总数 num_pages:页面总数 page_ranges:页码列表(页码从1开始)

方法:

page(num):获得一个Page对象,如果提供的页码不存在会抛出”InvalidPage”异常

异常:

InvalidPage:无效页码

PageNotAnInteger:page()传递的参数不是一个整数

EmptyPage:当page()传递有效值但该页面没有数据输出时

Page对象:

属性:

object_list:当前页上所有的数据列表

number:当前页的页码值

paginator:当前page对象关联的paginator对象

方法:

has_next():判断是否有下一页

has_previous():判断是否有上一页

has_other_pages():判断是否有上一页或下一页

next_page_number():返回下一页的页码,如果下一页不存在抛出InvalidPage异常

previous_page_number():返回上一页的页码,如果下一页不存在抛出InvalidPage异常

len():返回当前页的数据个数

#views.py
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.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生分页显示</title>
</head>
<body>
<ul>
{% for stu in students %}
<li>
{{stu.sname}}--{{stu.sgrade}}
</li>
{% endfor %}
</ul>

<ul>
{% for index in students.paginator.page_range %}
{% ifequal index students.number %}
<li>
{{index}}
</li>
{% else %}
<li>
<a href="/studentpage/{{index}}/">{{index}}</a>
</li>
{% endifequal %}
{% endfor%}
</ul>
</body>
</html>

Ajax

#sunck.js
$(document).ready(function(){
document.getElementById("btn").onclick=
function(){
$.ajax({
type:"get",
url:"/studentsinfo/",
dataType:"json",
success:function(data,status){
console.log(data)
var d=data["data"]
for(var i=0;i<d.length;i++){
document.write('<p>'+d[i][0]+'</p>')
}

}
})
}
})
#ajaxstudents.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<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>
</html>
#views.py
def ajaxstudents(request):
return render(request,
'myapp/ajaxstudents.html')

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

#urls.py
url(r'^studentsinfo/$',views.studentsinfo)

富文本

首先安装django-tinymce,配置完后需要重新执行迁移

1.在admin站点中使用:

配置settings.py

#settings.py
INSTALLED_APPS = [
...
'tinymce'
]

#富文本 文字加粗等
TINYMCE_DEFAULT_CONFIG={
'theme':'advanced',
'width':600,
'height':400,
}
#model.py
from tinymce.models import HTMLField
class Text(models.Model):
str=HTMLField()
#admin.py
from .models import Text
admin.site.register(Text)

2.在自定义视图中使用

#edit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>富文本</title>
<script type="text/javascript"
src="/static/tiny_mce/tiny_mce.js"></script> //这里会自动添加 不需要自己手动添加js文件
<script type="text/javascript">
tinyMCE.init({
'mode':'textareas',
'theme':'advanced',
'width':800,
'height':600
})
</script>
</head>
<body>
<form action="/saveedit/" method="post">
<textarea name="str">sunck is a good man</textarea>
<input type="submit" value="提交"/>
</form>
</body>
</html>
#views.py
def edit(request):
return render(request,'myapp/edit.html')

celery

问题:

1.用户发起request,并且要等待response返回,但是视图中有一些很耗时的操作(如发邮件),导致用户体验很差

2.每隔一段时间要同步一次数据,但http请求是需要触发的

解决:

1.将耗时的操作放到celery中执行

2.使用celery定时执行

celery:

任务:将耗时操作封装成一个函数

队列:将要执行的任务放入队列

工人:负责执行队列中的任务

代理:负责调度,在步数环境中使用redis

配置环境:

pip install celery
pip install celery-with-redis
pip install django-celery

配置settings.py

#settings.py
INSTALLED_APPS = [
...
'djcelery'
]

#celery
import djcelery
djcelery.setup_loader() #初始化
BROKER_URL='redis://123456@127.0.0.1:6379/0' #BROKER:代理密码 主机地址 redis的第0个库
CELERY_IMPORTS='myapp.task'

然后再project/myapp目录下创建task.py文件,然后直接迁移(不用生成迁移文件,即直接migrate)

在工程文件project目录中的project目录下(和settings.py同目录)创建celery.py文件

#celery.py
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE','whthas_home.settings')

app=Celery('portal')
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda:settings.INSTALLED_APPS)

@app.task(bind=True)
def def_task(self):
print('Request:{0!r}'.format(self.request))
#project/project/__init__.py中添加
from .celery import app as celery_app

Shiroha