关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
我的网站搭建の头像功能,文章回顾:
前面在开发上传头像功能的时候,留了位置写在线头像的功能。
有了在线头像功能,可以快速直接设置头像。效果如下,我选了16个萌萌的头像 ^_^
这16张图片存放在固定的静态目录中。使用Bootstrap的模态框弹窗显示。
由于该部分的头像不需要经常修改,为了节省服务器开支,将html代码直接写死。
<div class="modal fade avatar-online-modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title">捏脸 - 歪脖 (点一个试试)</h4> </div> <div class="modal-body" style="text-align: center;"> <div class="avatar_online_img"> <div> <img src="/static/media/avatar/online/n_1.jpg" /> <img src="/static/media/avatar/online/n_2.jpg" /> <img src="/static/media/avatar/online/n_3.jpg" /> <img src="/static/media/avatar/online/n_4.jpg" /> </div> <div> <img src="/static/media/avatar/online/n_5.jpg" /> <img src="/static/media/avatar/online/n_6.jpg" /> <img src="/static/media/avatar/online/n_7.jpg" /> <img src="/static/media/avatar/online/n_8.jpg" /> </div> <div> <img src="/static/media/avatar/online/w_1.jpg" /> <img src="/static/media/avatar/online/w_2.jpg" /> <img src="/static/media/avatar/online/w_3.jpg" /> <img src="/static/media/avatar/online/w_4.jpg" /> </div> <div> <img src="/static/media/avatar/online/w_5.jpg" /> <img src="/static/media/avatar/online/w_6.jpg" /> <img src="/static/media/avatar/online/w_7.jpg" /> <img src="/static/media/avatar/online/w_8.jpg" /> </div> </div> </div> </div> </div> </div>
再简单设置样式:
/*在线图片*/ .avatar_online_img img{ width: 96px; margin: 0 0 5px 5px; border: 1px #ccc solid; border-radius: 4px; cursor: pointer; } .avatar_online_img img:hover{ border-color: #bbb; box-shadow: 0 0 5px rgba(0,0,0,.25); } /*不同屏幕改变头像大小*/ @media (max-width:485px){ .avatar_online_img img{ width: 72px;} } @media (max-width:388px){ .avatar_online_img img{ width: 48px;} }
这个模态框我还没绑定按钮打开,因为“在线图片”那个按钮我还需要写其他代码。可以在“在线图片”按钮写代码弹出。
这里还需要思考一个问题。我们在后台如何分辨用户使用本地图片还是在线图片上传头像?
这个需要前端提交数据跟后台说清楚。
用户选择了在线图片,也就需要提交在线图片的地址给后台。
在form表单中添加隐藏字段。
<input type="hidden" id="avatar_online" name="avatar_online">
和前面文章我的网站搭建(第45天) 上传头像创建的form中一共有6个字段。
<!--图片裁剪参数--> <input type="hidden" id="avatar_x" name="avatar_x"> <input type="hidden" id="avatar_y" name="avatar_y"> <input type="hidden" id="avatar_width" name="avatar_width"> <input type="hidden" id="avatar_height" name="avatar_height"> <!--在线图片地址--> <input type="hidden" id="avatar_online" name="avatar_online"> <!--本地图片文件--> <input type="file" class="avatar-input" id="avatar-input" name="avatar_file" style="display:none">
那么,我们可以在后台处理提交数据的时候,判断avatar_file字段是否提交文件。
若没有提交,再判断avatar_online是否有填写在线图片的地址。
通过该方法可以分辨清楚用户采用哪种方式上传头像。
为了不让“本地图片”和“在线图片”两个字段相互干扰。
我们可以选择本地图片之后,清除“在线图片”相关字段的数据;
在选择在线图片之后,清除“本地图片”相关字段的数据。js代码如下:
//选择本地图片 function choose_local_img(){ var URL = window.URL || window.webkitURL; if(URL){ var files = this.files; if (files && files.length){ var file = files[0]; if (/^image\/\w+$/.test(file.type)) { var blobURL = URL.createObjectURL(file); image.cropper('reset').cropper('replace', blobURL); $('.avatar_crop .disabled').removeClass('disabled'); normal_tip('本地图片:可调整到最佳状态再上传'); $("#avatar_online").val(''); //去掉在线图片数据 } else { error_tip('请选择一张图片'); } } } } $("#avatar-input").bind('change', choose_local_img); //绑定事件 //在线图片 $('#online-img').click(function(){ normal_tip('在线图片:捏脸和歪脖系列头像,萌不'); $(".avatar-online-modal").modal('show'); }); //选择在线图片 $(".avatar_online_img img").click(function(){ $(".avatar-online-modal").modal('hide'); //设置在线图片 var path = $(this).attr('src'); image.cropper('replace', path); $("#avatar_online").val(path); $('.avatar_crop .disabled').removeClass('disabled'); //移除本地图片选择 var file = $("#avatar-input") file.after(file.clone().val("")); file.remove(); $("#avatar-input").bind('change', choose_local_img); //绑定事件 });
这里为了兼容清除file标签的文件选择信息。先移除标签,再添加进来。
但再添加进来的时候,需要重新绑定一次。
(相关上传头像代码,看我的网站搭建(第45天) 上传头像)
Django后台的代码,也修改如下:
@check_login def user_avatar_upload(request): """上传头像""" data = {} ##获取临时路径,用于保存图片 temp_folder = os.path.join(settings.BASE_DIR, 'static', 'temp') if not os.path.isdir(temp_folder): os.makedirs(temp_folder) temp_filename = uuid.uuid1().hex #纯文件名,没有后缀名 temp_path = os.path.join(temp_folder, temp_filename) #判断图片来源(本地上传 or 在线图片) if request.FILES.has_key('avatar_file'): #本地上传 avatar_file = request.FILES['avatar_file'] temp_path = temp_path + os.path.splitext(avatar_file.name)[-1] #加后缀名 #保存上传的文件 with open(temp_path, 'wb') as f: for chunk in avatar_file.chunks(): f.write(chunk) else: avatar_online = request.POST.get('avatar_online', '') print('-'*30+'1') print(avatar_online) #在线图片有效性验证 avatar_is_valid = False if len(avatar_online)>0: filename = os.path.split(avatar_online)[-1] avatar_online_path = os.path.join(settings.BASE_DIR, 'static/media/avatar/online', filename) #判断文件是否存在 avatar_is_valid = os.path.isfile(avatar_online_path) if not avatar_is_valid: data['success'] = False return HttpResponse(json.dumps(data), content_type="application/json") #复制图片到临时路径 temp_path = temp_path + os.path.splitext(avatar_online_path)[-1] shutil.copy(avatar_online_path, temp_path) #裁剪图片 top = int(float(request.POST['avatar_y'])) buttom = top + int(float(request.POST['avatar_height'])) left = int(float(request.POST['avatar_x'])) right = left + int(float(request.POST['avatar_width'])) #python2.7 pillow from PIL import Image im = Image.open(temp_path) #裁剪图片 crop_im = im.convert("RGBA").crop((left, top, right, buttom)).resize((64, 64), Image.ANTIALIAS) #设置背景颜色为白色 out = Image.new('RGBA', crop_im.size, (255,255,255)) out.paste(crop_im, (0, 0, 64, 64), crop_im) #保存图片 out.save(temp_path) #保存记录 avatar = request.user.set_avatar_url(temp_path) os.remove(temp_path) data['success'] = True data['avatar_url'] = avatar.avatar.url return HttpResponse(json.dumps(data), content_type="application/json")
大部分代码和我的网站搭建(第45天) 上传头像一样,前面部分加入在线图片判断和处理即可。
这里还有一个地方需要注意的。我将头像获取和设置代码使用了get方法获取头像记录。
在开发的过程中,发生一些错误。导致出现多条记录,get方法在获取多条记录会出错,改成filter即可解决问题。
avatar = User_Avatar.objects.filter(user=self.id)[0]
(本篇文章和前面两篇文章一脉相承,看不明白的话,先看看前面两篇文章。)
相关专题: Django评论库开发