django——文件上传_分页_ajax_富文本_celery
上传文件
概述
当Django在处理文件上传时,文件的数据被存储在request.FILES属性中
FILES只有在请求的方法为POST且提交的form表单带有enctype="multipart/form-data"属性的情况才会包含数据。否则,FILES将为一个空的类似字典的对象
FILES中的键为input的name属性值
上传界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form method="post" action="/upfile/" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="file">
<input type="file" name="file">
<input type="file" name="pic">
<input type="submit" value="上传">
</form>
</body>
</html>
文件存储路径
在static目录下创建名为media的目录
配置路径:
settings
# 文件上传的路径
MEDIA_URL = '/media/' # 访问资源的地址如 http://127.0.0.1:5000/media/1.jpg
# 写相对路径也可以
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
request.FILES数据结构
{
'file': [
<InMemoryUploadedFile: a.txt (text/plain)>,
<InMemoryUploadedFile: b.txt (text/plain)>
],
'pic': [
<InMemoryUploadedFile: c.jpg (image/jpeg)>
]
}
视图实现
from django.conf import settings
def upfile(request):
if request.method == "GET":
return render(request, "upfile.html")
else:
# print(request.FILES)
for name in request.FILES:
files = request.FILES.getlist(name)
# print(files)
for file in files:
#处理每个文件
filePath = r"%s\%s"%(settings.MEDIA_ROOT,file.name)
with open(filePath, "wb") as fp:
# 将文件数据切片写入描述符
for part in file.chunks():
fp.write(part)
return HttpResponse("上传文件成功")
图片生成缩略图
# 生成缩略图
from PIL import Image
im = Image.open('c.jpg')
print(im.format, im.size, im.mode)
# JPEG (840, 1024) RGB
im.thumbnail((100,200))
im.save("c1.jpg", "JPEG")
分页
Paginator对象

Page对象

示例
from django.core.paginator import Paginator
def students(request, num):
allStudents = Student.objects.all()
#分页 每页6条数据
paginator = Paginator(allStudents, 6)
print(paginator.count, paginator.num_pages, paginator.page_range)
pageStus = paginator.page(num)
return render(request, "students.html", {"stus":pageStus})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生信息</title>
</head>
<body>
<h1>学生信息</h1>
<ul>
{% for stu in stus %}
<li>{{ stu.name }}--{{ stu.grade }}--{{ stu.age }}</li>
{% endfor %}
</ul>
{% if stus.has_previous %}
<a href="/students/{{ stus.previous_page_number }}">上一页</a>
{% endif %} {% for index in stus.paginator.page_range %}
{% if index == stus.number %}
{{ index }}
{% else %}
<a href="/students/{{ index }}/">{{ index }}</a>
{% endif %}
{% endfor %}
{% if stus.has_next %}
<a href="/students/{{ stus.next_page_number }}">下一页</a>
{% endif %}
</body>
</html>
Ajax
问题
使用视图通过上下文向模板中传递数据,需要先加载完成模板的静态页面,再执行模板模型代码,生成最后的HTML代码,返回给浏览器,这个过程将页面与数据集成到了一起,扩展性差
解决
通过ajax的方式获取数据,再通过DOM操作将数据呈现到界面上
异步:如发邮件(注册的时候提示邮件已经发送成功,其实并没有) 能提高用户体验。 如豆瓣,防止页面卡死。
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>展示学生</title>
<script type="text/javascript" src="/static/js/jquery-3.1.1.min.js"></script>
</head>
<body>
<button id="btn">显示学生信息</button>
<ul id="stus">
</ul>
<script type="text/javascript">
$(document).ready(function () {
$("#btn").bind("click", function () {
/*
$.get("/allStudents/",{"a":1,"b":2},function (data, status) {
console.log("************************2");
console.log(data, status);
stus = data["data"];
for (var i = 0; i < stus.length; i++){
stu = stus[i];
$li = $("<li>"+stu.name+"---"+stu.age+"</li>");
$("#stus").append($li)
}
});
*/
$.ajax({
url:"/allStudents/",
type:"get",
data:{"a":1,"b":2,"c":3},
dataType:"json",
success:function (data, status) {
console.log("************************2");
console.log(data, status);
stus = data["data"];
for (var i = 0; i < stus.length; i++){
stu = stus[i];
$li = $("<li>"+stu.name+"&&&"+stu.age+"</li>");
$("#stus").append($li)
}
}
});
console.log("************************1");
});
});
</script>
</body>
</html>
def allStudents(request):
if request.method == "GET":
if not request.is_ajax():
return render(request, "allStudents.html")
else:
stus = Student.objects.all()
arr = []
for stu in stus:
arr.append({"name":stu.name, "age":stu.age})
return JsonResponse({"data":arr})
富文本
安装:pip install django-tinymce
在站点中使用
激活应用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myApp',
'tinymce',
]
配置
TINYMCE_DEFAULT_CONFIG={
'theme':'advanced',
'width':600,
'height':400
}
模型
from tinymce.models import HTMLField
class Article(models.Model):
title = models.CharField(max_length=20)
content = HTMLField()
admin.py
admin.site.register(Article)
在自定义页面中使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>书写博客</title>
<script type="text/javascript" src="/static/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
tinyMCE.init({
'mode':'textareas',
'theme':'advanced',
'width':600,
'height':400
});
</script>
</head> <body>
<form method="post" action="/tinymce/">
{% csrf_token %}
<input type="text" name="title" value=""><hr/>
<textarea name="article"></textarea><hr/>
<input type="submit" value="提交">
</form>
</body>
</html>
Celery
问题
用户发起request请求,并等待response返回。在本次views中,可能需要执行一段耗时的程序,那么用户会等待很长时间,造成不好的用户体验
网站每小时需要同步数据(天气预报信息),但是http是需要触发的,难道要一个小时请求一次吗?
解决方案
使用celery:将耗时的程序放到celery中执行 使用celery定时执行
celery
任务task:就是一个python函数
队列queue:将需要执行的任务加入队列中
工人worker:在一个新的进程中负责执行队列中的任务
代理broker:负责调度,在布置环境中使用redis
安装
pip install celery==3.1.25
pip install celery-with-redis==3.0
pip install django-celery==3.2.1
配置
激活应用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myApp',
'tinymce',
'djcelery',
]
配置redis
#celery
import djcelery
djcelery.setup_loader()
#配置redis数据库
#redis://:密码@ip:端口/库
BROKER_URL='redis://:sunck@127.0.0.1:6379/0'
#配置任务文件
CELERY_IMPORTS=("myApp.task")
创建任务文件,并分装任务
# 在应用目录下创建名为task.py的文件
# -*- coding:utf-8 -*-
from celery import task
import time
@task
def longIO():
print("开始耗时操作……")
time.sleep(5)
print("结束耗时操作……")
迁移
python manage.py migrate
生成celery所需要的表
添加celery.py文件
将已存在的celery.py添加到工程目录下的与工程目录同名的目录下
celery.py
from __future__ import absolute_import 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 debug_task(self):
print('Request: {0!r}'.format(self.request))
导入celery
在工程目录下的与工程目录同名的目录中的__init__.py文件中添加from .celery import app as celery_app
在视图使用任务
from myApp.task import longIO
def registe(request):
longIO.delay()
return HttpResponse("sunck is a good man")
启动redis
redis-server.exe redis.windows.conf
启动worker
python manage.py celery worker --loglevel=info
启动Django服务
python manage.py runserverdjango——文件上传_分页_ajax_富文本_celery的更多相关文章
- Django文件上传下载与富文本编辑框
django文件上传下载 上传 配置settings.py # 设定文件的访问路径,如:访问http://127.0.0.1:8000/media/就可以获取文件 MEDIA_URL = '/medi ...
- python_way day21 Django文件上传Form方式提交,原生Ajax提交字符处啊,Django文件上传之原生Ajax方式、jQuery Ajax方式、iframe方式,Django验证码,抽屉示例,
python_way day21 1.Django文件上传至Form方式 2.原生Ajax文件上传提交表单 使用原生Ajax好处:不依赖jquery,在发送一个很小的文件或者字符串的时候就可以用原生A ...
- django文件上传、图片验证码、抽屉数据库设计
1.Django文件上传之Form方式 settings.py, ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'd ...
- Django - 文件上传、Django组件 - 分页器(paginator)
一.文件上传准备知识 - Content-Type 1.请求头 - Content-Type Content-Type指的是请求体的编码类型,常见的类型共有3种: 1)application/x-ww ...
- django文件上传和序列化
django实现文件上传 使用form表单上传文件 html页面 <html lang="en"> <head> <meta charset=&quo ...
- django文件上传
-------------------上传图片-------------------1.model中定义属性类型为models.ImageField类型 pic=models.ImageField(u ...
- Python Web框架篇:Django文件上传
上传方式: - Form表单上传文件 - Ajax上传文件 - 基于form表单和iframe自己实现ajax请求 1,创建项目 2,settings配置(注册app01,static路径等等这些)及 ...
- Django文件上传(经典上传方式)
经典文件上传方式 创建URL from django.contrib import admin from django.urls import path from django.conf.urls i ...
- django 文件上传(阿里云oss)下载(支持大文件下载)
1.文件上传 Models 设计 class Upload_File(models.Model): image = models.FileField(upload_to='file/%Y/%m',de ...
随机推荐
- RHEL7-openldap安装配置一(服务器端安装配置)
LDAP的术语:entry:一个单独的单元,使用DN(distinguish name)区别attribute:entry的属性,比如,如果entry是组织机构的话,那么它的属性包括地址,电话,传真号 ...
- Red Hat7.2 上安装 MySQL5.5.58
1.首先查看linux版本:cat /etc/redhat-release Red Hat Enterprise Linux Server release 7.2 (Maipo) 2.Linux查看版 ...
- Spring Cloud环境搭建: Eureka Server
项目目录结构, 总共三个文件 ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── rockbb │ │ ...
- spring事务配置的两种方式
spring所有的事务管理策略类都继承自org.springframework.transaction.PlatformTransactionManager接口. <!-- 事务管理器配置,单数 ...
- (原)ubuntu挂载及开机自动挂载网络端的文件夹的方法
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/7160792.html 参考网址: http://blog.csdn.net/tlight/articl ...
- Linux安装配置maven以及搭建nexus私服(编写启动脚本)
2011年07月12日16:32 下面介绍在Linux操作系统下安装配置maven和搭建nexus私服. 一.安装前的准备 下载 jdk http://www.oracle.com/technetw ...
- 【RS】RankMBPR:Rank-Aware Mutual Bayesian Personalized Ranking for Item Recommendation - RankMBPR:基于排序感知的相互贝叶斯个性化排序的项目推荐
[论文标题]RankMBPR:Rank-Aware Mutual Bayesian Personalized Ranking for Item Recommendation ( WAIM 2016: ...
- lnmp+zabbix 3.2 的编译安装
yum install pcre* gcc gcc-c++ autoconf automake zlib libxml libjpeg freetype libpng gd curl zlib-dev ...
- Linux 源代码在线(http://lxr.linux.no/linux/)。
LXR 是一个通用的源代码索引器和交叉引用器 它提供了一个基于 web 的可浏览任意定义以及任意标识的用法. 它支持很多种语言. LXR 曾经被作为 “Linux 交叉引用器” 但是已经被证明它可以用 ...
- 进阶之路(基础篇) - 011 arduino api基础手册
arduino 函数 api 程序结构 在Arduino中, 标准的程序入口main函数在内部被定义, 用户只需要关心以下两个函数:void setup()void loop()setup() 函数用 ...