2 图片上传 展示.md

图片上传和展示

图片上传

上传表单和文件保存

  • self.request.files 的使用

  • Python 操作文件,写入数据

    获取一个表单上传的文件列表 可以使用 self.request.files.get('newimg'),

    参数填写 HTML 中的 <input type="file" name='newimg'>

    每个文件都是一个字典的形式{"filename":..., "content_type":..., "body":...}.

    form表单 enctype="multipart/form-data" ; 如果没用这种格式, 原生上传的数据可以调用 self.request.body 使用. 默认上传的文件是完全缓存在内存中的;

code

main.py
class UploadHandler(tornado.web.RequestHandler):
   """
   接受图片上传
   """

   def get(self, *args, **kwargs):
      self.render('upload.html')

   def post(self, *args, **kwargs):
  	# 提取表单中‘name’为‘newimg’的文件元数据   获取上传文件信息
  	img_files = self.request.files.get('newimg')  #
  	print(img_files) #[{"filename": ..., "content_type": ..., "body": ...},]

  	for img_file in img_files:
  		# img_file['filename']获取文件的名称  有些文件需要以二进制的形式存储
  		with open('./static/uploads/' + img_file['filename'], 'wb') as f:
  			f.write(img_file['body'])  # img_file['body']获取文件的内容
              
  	self.write({'msg':'got file: {}'.format(img_files[0]['filename'])})

ssh://pyvip@127.0.0.1:1234/home/pyvip/.virtualenvs/py3env/bin/python3 -u /home/pyvip/py_case/tornado2项目/app.py

upload.html
{% extends 'base.html' %}

{% block title %}
    list post page
{% end %}

{% block content %}
    {#entype 设置编码格式 上传文件:multipart/form-data#}
    <form action="/upload" enctype="multipart/form-data" method="post">
        <input type="file" name="newimg">
        <input type="submit">
    </form>
{% end %}

图片展示

用简单的目录检索来展示

使用 Python 标准库 glob

code

main.py
class IndexHandler(tornado.web.RequestHandler):
	"""
	首页
	"""

	def get(self, *args, **kwargs):
        # 获取该路径下所有的大图的路径
		imgs = photo.get_images('uploads')
		self.render('index.html', imgs=imgs)
index.html
{% extends 'base.html' %}

{% block title %}
    index page
{% end %}

{% block content %}
    {% for i in imgs %}
        <img src="{{ static_url(i) }}" width="666px">
    {% end %}

{% end %}



photo.py
import glob
import os


def get_images(path):
	"""
	获取static目录下 path目录里所有 .jpg 结尾的 文件
	:param path: uploads
	:return:
	"""
	os.chdir('static')
	imgs = glob.glob('{}/*.jpg'.format(path))
	os.chdir('..')
	return imgs


def get_images2(path):
    """
	获取static目录下 path目录里所有 .jpg 结尾的 文件
	:param path: static/uploads
	:return:
	"""
	images = []
	for file in glob.glob(path + '/*.jpg'):
		images.append(file)
	return images


def get_images3(path):
    """
	获取static目录下 path目录里所有 .jpg 结尾的 文件
	:param path: static/uploads
	:return:
	"""
	imgs = glob.glob('{}/*.jpg'.format(path))
	return imgs

缩略图生成

pip install pillow

使用 PIL

from PIL import Image
import glob, os

imgs = glob.glob('*.jpg')
for img in imgs:
    #os.path.splitext()将文件名和扩展名分开  
    file, ext = os.path.splitext(img)  
	
    im = Image.open(img)   # 打开一个jpg图像文件,注意是当前路径
    im.thumbnail((200, 200)) # 长200 宽200 的缩放
    # 保存  
    im.save("{}_{}x{}.jpg".format(file, 200, 200), "JPEG")

glob.glob() 返回所有匹配的文件路径列表

os.path.basename()

返回path最后的文件名。如果path以/或\结尾,那么就会返回空值。

s = '/static/uploads/1202983.jpg'
>>> os.path.basename(s)
'1202983.jpg'

main.py


        
class ExploreHandler(tornado.web.RequestHandler):
	"""
	发现页
	"""

	def get(self, *args, **kwargs):
		# 获取该路径下所有的大图的路径
        # ['./static/uploads/thumbs/1106620_200x200.jpg', './static/uploads/thumbs/1106622_200x200.jpg',...]
		imgs = photo.get_images('uploads/thumbs')
		self.render('explore.html', imgs=imgs)

        
        
 
class UploadHandler(tornado.web.RequestHandler):
	"""
	接受图片上传
	"""

	def get(self, *args, **kwargs):
		self.render('upload.html')

	def post(self, *args, **kwargs):
		# 提取表单中‘name’为‘newimg’的文件元数据   获取上传文件信息
		img_files = self.request.files.get('newimg', None)

		print(img_files)  # [{"filename": ..., "content_type": ..., "body": ...},]
		print(img_files[0]['filename'])  # 例:1178645.jpg

		file_size = self.request.headers.get('Content-Length')  # 18539
		print(file_size)

		if img_files:
			for img_file in img_files:
				# img_file['filename']获取文件的名称  有些文件需要以二进制的形式存储
				save_to = './static/uploads/{}'.format(img['filename'])
				with open(save_to, 'wb') as f:
					f.write(img_file['body'])  # img_file['body']获取文件的内容
                    
				# 生成缩略图
				photo.make_thumb(save_to) 
                
			self.write({'msg': 'got file: {}'.format(img_files[0]['filename'])})

		else:
			self.write({'msg': 'empty form data'})

explore.html

{% extends 'base.html' %}

{% block title %}
    explore page
{% end %}

{% block content %}
     {% for i in imgs %}
        <img src="{{ static_url(i) }}" width="200px">
    {% end %}
{% end %}

photo.py

import glob
import os
from PIL import Image


def make_thumb(path):
	"""
	为指定的path文件生成它所在目录的 thumbs 目录下的小图文件
	:param path: ./static/uploads/701728.jpg
	:return:
	"""
	im = Image.open(path)
	size = (200, 200)
	im.thumbnail(size)

	basename = os.path.basename(path)  # 701728.jpg
	dirname = os.path.dirname(path)  # ./static/uploads
	file, ext = os.path.splitext(basename)

	# ./ static / uploads / thumbs / 701728_200x200 .jpg
	save_thumb_to = os.path.join(dirname, 'thumbs', '{}_{}x{}{}'.format(file, *size, ext))
	im.save(save_thumb_to, "JPEG")

作业

图片上传后生成缩略图,并展示在 explore 页面(提交简单的代码就可以了,主要是自己动手尝试)

with open

app.py 与 static 同级 两种效果一样

with open("static/uploads/1.jpg","wb") as file:

with open("./static/uploads/1.jpg","wb") as file:

代码:

app.py

import os

import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options

from handlers import main

define('port', default='8000', type=int, help='Listening port')


class Application(tornado.web.Application):
   def __init__(self):
      handlers = [
         (r'/', main.IndexHandler),
         (r'/explore', main.ExploreHandler),
         (r'/post/(?P<post_id>[0-9]+)', main.PostHandler),
         (r'/upload', main.UploadHandler),
      ]
      settings = dict(
         debug=True,
         template_path='template',
         static_path='static',   # 相对路径
         # static_path=os.path.join(os.path.dirname(__file__), 'static'),  # 绝对路径
      )

      super(Application, self).__init__(handlers, **settings)


application = Application()

if __name__ == '__main__':
   tornado.options.parse_command_line()
   application.listen(options.port)
   print("Server start on port {}".format(str(options.port)))
   tornado.ioloop.IOLoop.current().start()

main.py

import tornado.web
from utils import photo
import os


class IndexHandler(tornado.web.RequestHandler):
	"""
	首页
	"""

	def get(self, *args, **kwargs):
		# 获取该路径下所有的大图的路径
		imgs = photo.get_images('uploads')
		self.render('index.html', imgs=imgs)


class ExploreHandler(tornado.web.RequestHandler):
	"""
	发现页
	"""

	def get(self, *args, **kwargs):
		# 获取该路径下所有的大图的路径
		imgs = photo.get_images('uploads/thumbs')
		self.render('explore.html', imgs=imgs)


class PostHandler(tornado.web.RequestHandler):
	"""
	详情页
	"""

	def get(self, post_id):
		self.render('post.html', post_id=post_id)


class UploadHandler(tornado.web.RequestHandler):
	"""
		接受图片上传
		"""

	def get(self, *args, **kwargs):
		self.render('upload.html')

	def post(self, *args, **kwargs):
		# 提取表单中‘name’为‘newimg’的文件元数据   获取上传文件信息
		img_files = self.request.files.get('newimg')

		print(img_files)  # [{"filename": ..., "content_type": ..., "body": ...},]
		print(img_files[0]['filename'])  # 例:1178645.jpg

		file_size = self.request.headers.get('Content-Length')  # 18539
		print(file_size)

		if img_files:
			for img in img_files:
				# img_file['filename']获取文件的名称  有些文件需要以二进制的形式存储
				save_to = './static/uploads/{}'.format(img['filename'])
				with open(save_to, 'wb') as f:
					f.write(img['body'])  # img_file['body']获取文件的内容
				# 生成缩略图
				photo.make_thumbs(save_to)

			self.write({'msg': 'got file: {}'.format(img_files[0]['filename'])})

		else:
			self.write({'msg': 'empty form data'})

photo.py

import os
import glob
from PIL import Image


def get_images(path):
	"""
	获取static目录下 path目录里所有 .jpg 结尾的 文件
	:param path: uploads
	:return:
	"""
	os.chdir('static')
	images = glob.glob('{}/*.jpg'.format(path))
	os.chdir('..')
	return images


def make_thumbs(path):
	"""
	为指定的path文件生成它所在目录的 thumbs 目录下的小图文件
	:param path: ./static/uploads/701728.jpg
	:return:
	"""

	# ./ static / uploads / 701728.jpg
	im = Image.open(path)
	size = (200, 200)
	im.thumbnail(size)
	# ./ static / uploads /thumbs/ 701728_200x200.jpg
	dirname = os.path.dirname(path)  # ./ static / uploads
	basename = os.path.basename(path)  # 701728.jpg
	file, ext = os.path.splitext(basename)
	save_thumbs_to = os.path.join(dirname, 'thumbs', '{}_{}x{}{}'.format(file, *size, ext))
	im.save(save_thumbs_to, "JPEG")

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Title{% end %}</title>
</head>
<body>
    <div style="width: 800px; text-align: center">
        {% block content %}
            base content
        {% end %}
    </div>


</body>
</html>

index.html

{% extends 'base.html' %}

{% block title %}
    index page
{% end %}

{% block content %}
    {% for i in imgs %}
        <img src="{{ static_url(i) }}" width="666px">
    {% end %}

{% end %}



explore.html

{% extends 'base.html' %}

{% block title %}
    explore page
{% end %}

{% block content %}
     {% for i in imgs %}
        <img src="{{ static_url(i) }}" width="200px">
    {% end %}
{% end %}

post.html

{% extends 'base.html' %}

{% block title %}
    post page
{% end %}

{% block content %}
    <img src="{{ static_url("images/{}.jpg".format(post_id)) }} " width=666">
{% end %}

upload.html

{% extends 'base.html' %}

{% block title %}
    list post page
{% end %}

{% block content %}
    {#entype 设置编码格式 上传文件:multipart/form-data#}
    <form action="/upload" enctype="multipart/form-data" method="post">
        <input type="file" name="newimg">
        <input type="submit">
    </form>
{% end %}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值