美文网首页django2.1 博客系统
八、Django2.1 搭建多用户的博客网站——头像上传

八、Django2.1 搭建多用户的博客网站——头像上传

作者: 27efec53a72d | 来源:发表于2019-01-29 00:11 被阅读88次

    目录:Django 2.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/ 页面如图

    静态头像.png

    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/

    测试头像插件1.png

    点击“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”,头像替换成功:

    头像替换成功.png

    查看数据表中的 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”按钮,效果如下图

    优化后的头像上传弹窗.png

    选择图片,最后点击 “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/登录后可见页面如下图:

    超级管理员后台.png

    点击 User infos 栏目会打开如下页面:


    User infos.png

    5、遗留问题

    访问 http://127.0.0.1:8000/admin/ 登录admin(密码:helloworld)时,会提示密码错误,但是我没有修改过admin的密码,所以导致超级用户无法登陆。不知道是什么原因导致的。

    在无法找回超级管理员的密码时,可以新建一个超级管理员的账号,然后再进入后台修改admin的密码。

    新建一个超级管理员的账号的命令:

    python manage.py createsuperuser
    

    相关文章

      网友评论

        本文标题:八、Django2.1 搭建多用户的博客网站——头像上传

        本文链接:https://www.haomeiwen.com/subject/odbzjqtx.html