八、Django2.1 搭建多用户的博客网站——头像上传
目录:Django 2.1 从零开始搭建博客网站系列
服务器环境搭建(选学)
小试牛刀——简单的博客网站
庖丁解牛——多用户的博客网站之用户模块
- 三、Django2.1 搭建多用户的博客网站——登录
- 四、Django2.1 搭建多用户的博客网站——注册
- 五、Django2.1 搭建多用户的博客网站——修改密码
- 六、Django2.1 搭建多用户的博客网站——重置密码
- 七、Django2.1 搭建多用户的博客网站——维护个人详细信息
- 八、Django2.1 搭建多用户的博客网站——头像上传
- 九、Django2.1 搭建多用户的博客网站——用户模块小结
庖丁解牛——多用户的博客网站之文章模块
- 十、Django2.1 搭建多用户的博客网站——文章栏目
- 十一、Django2.1 搭建多用户的博客网站——简单的文章发布
- 十二、Django2.1 搭建多用户的博客网站——使用Markdown发布文章
- 十三、Django2.1 搭建多用户的博客网站——修改和删除文章
- 十四、Django2.1 搭建多用户的博客网站——向用户展示文章
- 十五、Django2.1 搭建多用户的博客网站——文章模块小结
华丽转身——多用户的博客网站之扩展功能
- 十六、Django2.1 搭建多用户的博客网站——文章点赞功能
- 十七、Django2.1 搭建多用户的博客网站——统计文章浏览次数
- 十八、Django2.1 搭建多用户的博客网站——文章评论功能
- 十九、Django2.1 搭建多用户的博客网站——使用自定义模板标签
- 二十、Django2.1 搭建多用户的博客网站——文章标签
- 未完待续
项目源码下载:https://github.com/jt1024/lehehe
正文:
在完善个人详细信息的时候,右侧我们那预留了一个地方,暂时用“picture”占位,本节我们将在这里展示用户的头像。
1、使用静态文件作为头像
新增资源文件 ./static/images/avatar.png
在 ./templates/account/myself.html 中用以下代码代替 <p>picture</p>
{% load staticfiles %}
<div style="margin-right:100px">
<img name="user_face" src="{% static 'images/avatar.png' %}" class="img-circle" width="270px" id="my_photo">
</div>
<div style="margin-right:100px">
<button class="btn btn-primary btn-lg" id="upload_image" onclick="upload_image_layer()">upload my photo</button>
</div>
访问 http://127.0.0.1:8000/account/my-information/ 页面如图
2、头像上传
2.1 下载插件并整合到项目
下载 ImgCrop 文件包
复制 ImgCrop/css/style.css 到本项目的 static/css 并更名为 imagecrop.css ,然后修改一下样式:
.container {
width: 400px;
margin: 0 auto 0 0;
position: relative;
font-family: 微软雅黑;
font-size: 12px;
}
复制 ImgCrop/jquery-1.11.1.min.js 到本项目的 ./static/js
复制 ImgCrop/js/cropbox-min.js 到本项目的 ./static/js
2.2 简单地使用插件模拟头像上传
在 ./account/views.py 中增加 my_image 方法
def my_image(request):
return render(request, 'account/imagecrop.html')
创建 ./templates/account/imagecrop.html 并把 ImgCrop/index.html的代码复制过来,最后结合项目修改代码如下:
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'css/imagecrop.css' %}">
<div class="container">
<div class="imageBox">
<div class="thumbBox"></div>
<div class="spinner" style="display: none"></div>
</div>
<div class="action">
<!-- <input type="file" id="file" style=" width: 200px">-->
<div class="new-contentarea tc">
<a href="javascript:void(0)" class="upload-img">
<label for="upload-file">请先选择图片...</label>
</a>
<input type="file" class="" name="upload-file" id="upload-file"/>
</div>
<input type="button" id="btnCrop" class="Btnsty_peyton" value="OK"><!--注意这行代码,添加了 id="btnCrop" -->
<input type="button" id="btnZoomIn" class="Btnsty_peyton" value="+">
<input type="button" id="btnZoomOut" class="Btnsty_peyton" value="-">
</div>
<div class="cropped"></div>
</div>
<script src="{% static 'js/jquery-1.11.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/cropbox-min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/csrf.js' %}"></script>
<script type="text/javascript">
$(window).load(function() {
var options =
{
thumbBox: '.thumbBox',
spinner: '.spinner',
imgSrc: ''
}
var cropper = $('.imageBox').cropbox(options);
var img="";
$('#upload-file').on('change', function(){
var reader = new FileReader();
reader.onload = function(e) {
options.imgSrc = e.target.result;
cropper = $('.imageBox').cropbox(options);
getImg();
}
reader.readAsDataURL(this.files[0]);
this.files = [];
})
$('#btnCrop').on('click', function(){
alert("图片上传喽");
})
function getImg(){
img = cropper.getDataURL();
$('.cropped').html('');
$('.cropped').append('<img src="'+img+'" align="absmiddle" style="width:180px; margin-top:4px; border-radius:180px; box-shadow:0px 0px 12px #7E7E7E;"> <p>180px*180px</p>');
$('.cropped').append('<img src="'+img+'" align="absmiddle" style="width:128px; margin-top:4px; border-radius:128px; box-shadow:0px 0px 12px #7E7E7E;"> <p>128px*128px</p>');
$('.cropped').append('<img src="'+img+'" align="absmiddle" style="width:64px; margin-top:4px; border-radius:64px; box-shadow:0px 0px 12px #7E7E7E;" > <p>64px*64px</p>');
}
$(".imageBox").on("mouseup",function(){ getImg();});
$('#btnZoomIn').on('click', function(){ cropper.zoomIn();})
$('#btnZoomOut').on('click', function(){cropper.zoomOut(); })
});
</script>
在 ./account/urls.py 增加以下代码
path('my-image/', views.my_image, name="my_image"),
运行Django,访问 http://127.0.0.1:8000/account/my-image/
点击“OK”,弹出一个弹窗,此时只是模拟效果,头像并没有真正上传
测试头像插件2.png
2.3 实现真正的头像上传功能
修改 ./account/models.py 中的数据模型 UserInfo,增加如下字段
photo = models.ImageField(blank=True)
执行如下代码迁移数据库
python manage.py make migrations
python manage.py migrate
此时数据库中新增数据表account_userinfo
account_userinfo.png
在 ./account/forms.py 中修改 UserInfoForm
class UserInfoForm(forms.ModelForm):
class Meta:
model = UserInfo
fields = ("school", "company", "profession", "address", "aboutme", "photo")
修改 ./account/views.py 中的 my_image 方法
@login_required(login_url='/account/login')
def my_image(request):
if request.method == 'POST':
img = request.POST['img']
userinfo = UserInfo.objects.get(user=request.user.id)
userinfo.photo = img
userinfo.save()
return HttpResponse("1")
else:
return render(request, 'account/imagecrop.html', )
把 csrf.js 文件(附下载链接)复制到 ./static/js 里
修改 ./templates/account/imagecrop.html 中的 $('#btnCrop')方法
把这几行代码
$('#btnCrop').on('click', function(){
alert("图片上传喽");
})
替换为下面的代码
$('#btnCrop').on('click', function(){
//alert("图片上传喽");
$.ajax({
url: '{% url "account:my_image" %}',
type: 'POST',
data: {"img": img},
success: function(e){
location.href= "{% url 'account:my_information' %}"
},
})
})
修改 ./templates/account/myself.html 中的头像显示代码为下面的代码
{% load staticfiles %}
<div style="margin-right:100px">
<!--img name="user_face" src="{% static 'images/newton.jpg' %}" class="img-circle" width="270px" id="my_photo"-->
{% if userinfo.photo %}
<img src="{{ userinfo.photo | striptags }}" class="img-circle" id="my_photo" name="user_face">
{% else %}
<img name="user_face" src="{% static 'images/avatar.png' %}" class="img-circle" id="my_photo">
{% endif %}
</div>
运行Django,访问 http://127.0.0.1:8000/account/my-image/ 最后点击 “OK”,头像替换成功:
查看数据表中的 photo 字段,已存入
头像已存入数据库.png
3、优化头像上传
比较好的体验是,点击“upload my photo”按钮,弹出上传头像的弹窗,在弹窗中进行上传操作。layui 插件可以很好的满足我们的需求。
通过本链接下载layui插件或者官网http://www.layui.com下载,下载后把 layer.js 文件和 skin 目录都复制到本项目的 ./static/js 目录里。
修改 ./templates/account/myself.html,在{% endblock %} 之前增加以下代码
<script type="text/javascript" src='{% static "js/jquery.js" %}'></script>
<script type="text/javascript" src="{% static 'js/layer.js'%}"></script>
<script>
function upload_image_layer(){
layer.open({
title:"上传头像",
area: ['650px', '600px'],
type:2,
content:"{% url 'account:my_image' %}",
});
}
</script>
修改 ./templates/account/imagecrop.html 中的 $('#btnCrop')方法如下
$('#btnCrop').on('click', function(){
//alert("图片上传喽");
$.ajax({
url: '{% url "account:my_image" %}',
type: 'POST',
data: {"img": img},
success: function(e){
//location.href= "{% url 'account:my_information' %}"
if(e == "1"){
parent.location.reload();
} else {
alert("sorry, you are not lucky. the picutre can't been uploaded.")
}
},
})
})
运行Django,访问 http://127.0.0.1:8000/account/my-information/ 点击“upload my photo”按钮,效果如下图
选择图片,最后点击 “OK”,头像替换成功:
头像替换成功.png
4、超级管理员管理个人详细信息
我们用户的详细信息能不能在超级管理员后台的界面中管理呢?当然能!
在 ./account/admin.py 增加以下代码
from .models import UserInfo
class UserInfoAdmin(admin.ModelAdmin):
list_display = ("user", 'school', 'company', 'profession', 'address', 'aboutme', 'photo')
list_filter = ("school", "company", "profession")
admin.site.register(UserInfo, UserInfoAdmin)
访问http://127.0.0.1:8000/admin/登录后可见页面如下图:
点击 User infos 栏目会打开如下页面:
User infos.png
5、遗留问题
访问 http://127.0.0.1:8000/admin/ 登录admin(密码:helloworld)时,会提示密码错误,但是我没有修改过admin的密码,所以导致超级用户无法登陆。不知道是什么原因导致的。
在无法找回超级管理员的密码时,可以新建一个超级管理员的账号,然后再进入后台修改admin的密码。
新建一个超级管理员的账号的命令:
python manage.py createsuperuser