学习Django的最终目的还是应用,尤其是漂亮的应用。今天小编我要教你利用Django开发一个经典的用户头像上传和变更的app,主要实现以下功能场景。
-
用户点击现有头像,弹出一个图片上传和编辑窗口。
-
用户上传图片,对图片进行缩放和裁剪,并可以预览编辑过的头像。
-
用户点击确认上传,保存编辑过后的图片,并实时更新头像。
这个小应用的功能不亚于知乎,百度和CSDN上用户头像上传和变更的功能,可以直接应用到你的app里。最终效果如下图所示:
总体开发思路
我们前端使用Bootstrap和jQuery cropper实现图片的上传,剪切和预览。后端Django对上传的图片进行裁剪存储,删除老的头像,并通过Ajax实时更新新头像。jQuery cropper是一款使用简单且功能强大的图片剪裁jquery插件。该插件支持图片放大,缩小,旋转,裁剪和预览等功能。
注意: jQuery cropper只提供了图片裁剪的坐标(x, y, 高度,宽度),并没有对图片本身进行裁剪。Django是在接收了cropper通过json反馈来的坐标后才对图片进行了真正的裁剪。因为我们需要对图片进行编辑,请确保你已经安装了python的pillow图片库。
Django代码
我们先创建一个名叫myaccount的app, 定义UserProfile的模型,编写URLConfs和视图,最后编写模板,在模板里加入Bootstrap和jQuery cropper。
#models.py
这里UserProfile模型对于Django自带的User模型进行了1对1的扩展,加入了头像Avatar和电话等补充信息。如果你不清楚如何对用户资料进行扩展,请先阅读此教程 。(django-allauth教程(2): 用户个人资料UserProfile扩展与编辑)
from django.db import models
from django.contrib.auth.models import User
import uuid
import os
# Create your models here.
def user_directory_path(instance, filename):
ext = filename.split('.')[-1]
filename = '{}.{}'.format(uuid.uuid4().hex[:10], ext)
sub_folder = 'file'
if ext.lower() in ["jpg", "png", "gif"]:
sub_folder = "avatar"
if ext.lower() in ["pdf", "docx"]:
sub_folder = "document"
return os.path.join(str(instance.user.id), sub_folder, filename)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
uid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)
org = models.CharField('Organization', max_length=128, blank=True)
avatar = models.ImageField(upload_to=user_directory_path, default=os.path.join("avatar", "default.jpg"), verbose_name="头像")
join_date = models.DateTimeField("join date", blank=True, null=True, auto_now_add=True)
mod_date = models.DateTimeField("Mod date", blank=True, null=True, auto_now=True)
class Meta:
verbose_name = 'User Profile'
def __str__(self):