通过项目来深入理解tornado(七):aiofiles实现异步文件上传
通过项目来深入理解tornado(七):aiofiles实现异步文件上传
前言
现在论坛需要新增一个功能,就是创建小组
数据表如下
models.py
from datetime import datetime
from peewee import *
from tornado_bbs.models import BaseModel
from apps.users.models import User
class CommunityGroup(BaseModel):
creator = ForeignKeyField(User, verbose_name="创建者")
name = CharField(max_length=100, null=True, verbose_name="名称")
category = CharField(max_length=20, verbose_name="分类", null=True)
front_image = CharField(max_length=200, null=True, verbose_name="封面图")
desc = TextField(verbose_name="简介")
notice = TextField(verbose_name="公告")
#小组的信息
member_nums = IntegerField(default=0, verbose_name="成员数")
post_nums = IntegerField(default=0, verbose_name="帖子数")
@classmethod
def extend(cls):
return cls.select(cls, User.id, User.nick_name).join(User)
HANDLE_STATUS = (
("agree", "同意"),
("refuse", "拒绝")
)
class CommunityGroupMember(BaseModel):
user = ForeignKeyField(User, verbose_name="用户")
community = ForeignKeyField(CommunityGroup, verbose_name="社区")
status = CharField(choices=HANDLE_STATUS, max_length=10, null=True, verbose_name="处理状态")
handle_msg = CharField(max_length=200, null=True, verbose_name="处理内容")
apply_reason = CharField(max_length=200, verbose_name="申请理由")
handle_time = DateTimeField(default=datetime.now(), verbose_name="加入时间")
这里存在一个问题,就是peewee它没有image字段或者file字段,所以后面验证就需要自己来做了。
重头戏来了
handler.py
from tornado_bbs.handler import BaseHandler
from tools.auth_dec import authenticated
from .forms import CommunityGroupForm
import aiofiles
import uuid
from .models import CommunityGroup
class GroupHandler(BaseHandler):
async def get(self, *args, **kwargs):
pass
@authenticated
async def post(self, *args, **kwargs):
re_data = {}
form = CommunityGroupForm(self.request.body_arguments)
if form.validate():
# 需要自己做文件的验证
files = self.request.files.get("front_image", None)
if files:
new_file=''
for file in files:
new_file = file['filename'] + uuid.uuid4().hex
file_path = os.path.join(self.settings['media_path'], new_file)
async with aiofiles.open(file_path, 'wb') as f:
await f.write(file['body'])
group = await self.application.objects.create(CommunityGroup, creator=self.current_user,
name=form.name.data,
categoru=form.category.data,
front_image=new_file,
desc=form.desc.data,
notice=form.notice.data)
re_data['id'] = group.id
else:
self.set_status(400)
re_data['front_image'] = '请上传图片'
else:
self.set_status(400)
for fields in form.errors:
re_data[fields] = form.errrors[fields][0]
self.finish(re_data)
总结:
首先,form = CommunityGroupForm(self.request.body_arguments)
这个里面因为有文件存在,所以不能用之前的form_json.# 另如果前端传递过来的是json数据。需要用self.request.body获取并且需要decode(utf8)然后json.loads()
上传的文件存放在self.request.files属性里面,格式需要看前端怎么放
文件名字在file[filename]里,文件内容file[body]
最后就是aiofiles里,github里面的开源项目。
文件路径需要用,项目路径加上文件名称,而项目路径可以用os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
至此,文件上传功能完成

浙公网安备 33010602011771号