到目前为止咱们的博客处理的都是文字。现代互联网早就进入了“读图”时代,图片的维护、展现也就至关重要。html
上一章中预留了avatar字段,用来保存用户上传的头像,如今咱们来实现这个功能。python
图片属于一种媒体文件,它与静态文件相似,须要设置一个统一的目录,便于集中存储和访问。git
这类须要框架统一设置的参数,固然应该在/my_blog/settings.py
中。在底部加上:github
/my_blog/settings.py ... # 媒体文件地址 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_ROOT和MEDIA_URL是用户上传文件保存、访问的位置:django
Profile
中咱们设置了upload_to参数。有了这个参数,文件上传后将自动保存到项目根目录的media
文件夹中。 os.path.join(MEDIA_ROOT, 'media/')
指定了media文件夹的位置。Django框架擅长的是对逻辑的处理,而对图片这类文件的处理则很是的耗时。所以在实际的生产环境中(即产品上线以后),一般是有专门的Web服务器来处理文件的访问。服务器
而在开发阶段咱们不会在乎效率问题,因此Django也提供了方法,让开发服务器可以处理图片。框架
在/my_blog/urls.py
添加下面的语句:学习
/my_blog/urls.py ... # 新引入的模块 from django.conf import settings from django.conf.urls.static import static urlpatterns = [ ... ] #添加这行 urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
这样就为之后上传的图片配置好了URL路径。网站
回顾一下,avatar
的字段已经在上一章写好了:ui
/userprofile/models.py ... class Profile(models.Model): ... avatar = models.ImageField(upload_to='avatar/%Y%m%d/', blank=True) ...
upload_to
指定了图片上传的位置,即/media/avatar/%Y%m%d/
。%Y%m%d
是日期格式化的写法,会最终格式化为系统时间。好比说图片上传是2018年12月5日,则图片会保存在/media/avatar/2018205/
中。
注意ImageField
字段不会存储图片自己,而仅仅保存图片的地址。记得用pip指令安装Pillow。
表单类在前面也写好了,不用修改:
/userprofile/forms.py ... class ProfileForm(forms.ModelForm): class Meta: model = Profile fields = ('phone', 'avatar', 'bio')
接着须要修改视图,使之可以对图片进行处理:
/userprofile/views.py ... @login_required(login_url='/userprofile/login/') def profile_edit(request, id): ... # 修改本行 # 上传的文件保存在 request.FILES 中,经过参数传递给表单类 profile_form = ProfileForm(request.POST, request.FILES) if profile_form.is_valid(): ... # 添加在 profile.bio = profile_cd['bio'] 后面 # 若是 request.FILES 存在文件,则保存 if 'avatar' in request.FILES: profile.avatar = profile_cd["avatar"] ...
request.FILES
中,所以须要修改表单类的参数,将它一并传递进去。request.FILES
中存在键为avatar
的元素,则将其赋值给profile.avatar
(注意保存的是图片地址);不然不进行处理。修改模板文件,添加代码显示、处理用户的头像:
/templates/userprofile/edit.html ... {% if profile.avatar %} <div class="col-md-4">头像</div> <img src="{{ profile.avatar.url }}" style="max-width: 20%; border-radius: 15%;" class="col-md-4"> {% else %} <h5 class="col-md-4">暂无头像</h3> {% endif %} <br> <br> <form ... enctype="multipart/form-data">{% csrf_token %} <!-- avatar --> <div class="form-group"> <label for="avatar">上传头像</label> <input type="file" class="form-control-file" name="avatar" id="avatar"> </div> ...
{% if ... %}
判断用户是否上传头像。<img>
标签用于显示图片内容;在style
属性中规定了图片的最大宽度并带有一点的圆角。enctype="multipart/form-data"
属性,才可以正确上传图片等文件。<input type="file" ...>
标签用于上传图片。启动服务器,刷新用户信息页面:
点击选择图片,上传一张图片后点击提交:
查看一下项目目录,生成了新的文件夹media/avatar/20181205/
,其中存储了该头像文件;在SQLiteStudio中查看avatar
字段,其保存的是文件的url地址。
除了上传,图片的处理还包括验证格式、改变尺寸、改名、裁剪、美化等多种多样的需求。若是上传的图片重名,会致使报错吗?请试试看。
更改图片仅仅会改变字段中存储的url,并不会真正删除图片自己。所以在处理大容量文件时要当心,须要额外的方法进行清理。
本章学习了经过表单上传文件的基础知识。更加高级的文件处理手段还需在探索中不断发掘。你还能够利用BootStrap知识,美化我的信息外观,使它像一个完善的产品级页面。
转载请告知做者并注明出处。