通過項目來深入理解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__)))

  

至此,文件上傳功能完成

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM