Django搭建个人博客:上传头像图片

到目前为止我们的博客处理的都是文字。现代互联网早就进入了“读图”时代,图片的维护、展示也就相当重要。

上一章中预留了avatar字段,用来保存用户上传的头像,现在我们来实现这个功能。

必要的设置

图片属于一种媒体文件,它与静态文件类似,需要设置一个统一的目录,便于集中存储和访问。

这类需要框架统一设置的参数,当然应该在/my_blog/settings.py中。在底部加上:

/my_blog/settings.py

...

# 媒体文件地址
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

MEDIA_ROOTMEDIA_URL是用户上传文件保存、访问的位置:

  • 在前面的Profile中我们设置了upload_to参数。有了这个参数,文件上传后将自动保存到项目根目录的media文件夹中。 os.path.join(MEDIA_ROOT, 'media/')指定了media文件夹的位置。

  • MEDIA_URL代表用户通过URL来访问这个本地地址的URL。设置好这个参数后,用户就可以通过解析url,很方便的获取文件的地址。这样做的好处是避免的硬编码,让代码更容易维护。

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路径。

编写MTV

回顾一下,avatar的字段已经在上一章写好了:

/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知识,美化个人信息外观,使它像一个完善的产品级页面。

转载请告知作者并注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容