django中博客后台将图片上传作为用户头像

时间:2022-09-19 20:23:02

添加上传目录

# 如果不添加上传目录,仍然可以上传成功,默认为project目录,如果models.py定义了upload_to="目录名称",则会上传到"project/目录名称"这个目录,如果添加了如下配置,会上传到"project/media"目录或者project/media/upload_to="目录名称"/:

settings.py

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

后台注册页面

# ajax在提交图片到后台的时候,不能直接将图片作为字典传递,而是formData。

例:

var formData = new FormData;

formData.append("username", $("#id_username").val());
formData.append("password", $("#id_password").val());
formData.append("re_password", $("#id_re_password").val());
formData.append("email", $("#id_email").val());
// 这里传递的是文件对象,是为了能够定位文件,后台获取到这个文件对象后会通过models字段单中的upload_to="avator"参数传递到服务器目录。
formData.append("avatar", $("#id_avatar")[0].files[0]);
formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
django中博客后台将图片上传作为用户头像django中博客后台将图片上传作为用户头像
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/backend.css">

    <div class="container register">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
{#                form添加novalidate参数,代表取消前端h5的验证,比如邮箱格式验证#}
                <form novalidate action="/register/" method="post" class="form-horizontal" enctype="multipart/form-data">
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="{{ form_obj.username.id_for_label }}" class="col-sm-2 control-label">
                            {{ form_obj.username.label }}
                        </label>
                        <div class="col-sm-8">
                            {{ form_obj.username }}
                            <span class="help-block">{{ form_obj.username.errors.0 }}</span>
                        </div>
                    </div>


                    <div class="form-group">
                        <label for="{{ form_obj.password.id_for_label }}" class="col-sm-2 control-label">
                            {{ form_obj.password.label }}
                        </label>
                        <div class="col-sm-8">
                            {{ form_obj.password }}
                            <span class="help-block">{{ form_obj.password.errors.0 }}</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label for="{{ form_obj.re_password.id_for_label }}" class="col-sm-2 control-label">
                            {{ form_obj.re_password.label }}
                        </label>
                        <div class="col-sm-8">
                            {{ form_obj.re_password }}
                            <span class="help-block">{{ form_obj.re_password.errors.0 }}</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label for="{{ form_obj.email.id_for_label }}" class="col-sm-2 control-label">
                            {{ form_obj.email.label }}
                        </label>
                        <div class="col-sm-8">
                            {{ form_obj.email }}
                            <span class="help-block">{{ form_obj.email.errors.0 }}</span>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">
                            头像
                        </label>
                        <div class="col-sm-8">
                            <label for="id_avatar"><img id="avatar-img" src="/static/img/default.png"></label>
                            <input type="file" id="id_avatar" style="display: none;" name="avatar" accept="image/*">
                        </div>
                    </div>

                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-8">
                            <button id="reg-submit" type="button" class="btn btn-success">注册</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>


{#    <script src="/static/js/bootstrap.min.js"></script>#}
    <script src="/static/js/jquery-1.12.4.js"></script>
    <script>
        $("#id_avatar").change(function () {
            // 创建一个文件读取对象
            var fileReader = new FileReader;
            // 在更改前端图片之前,把文件内容读取完
            fileReader.readAsDataURL(this.files[0]); // 读取文件是需要时间的
            // 文件读取完后,重新加载到img当中
            fileReader.onload = function () {
                $("#avatar-img").attr("src", fileReader.result);
            }
        });

        $("#reg-submit").click(function () {
            var formData = new FormData;
            formData.append("username", $("#id_username").val());
            formData.append("password", $("#id_password").val());
            formData.append("re_password", $("#id_re_password").val());
            formData.append("email", $("#id_email").val());
            // 这里传递的是文件对象,是为了能够定位文件,后台获取到这个文件对象后会通过models字段单中的upload_to="avator"参数传递到服务器目录。
            formData.append("avatar", $("#id_avatar")[0].files[0]);
            formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());

            /*
            console.log($("#id_avatar"));
            // 获取到了是一个jquery对象
            // jQuery.fn.init [input#id_avatar, context: document, selector: "#id_avatar"]

            console.log($("#id_avatar")[0]);
            // 获取到了input整个标签
            // <input type="file" id="id_avatar" style="display:none" name="avatar">

            console.log($("#id_avatar")[0].files);
            // 获取了input标签当中的type="file"类型中的内容
            //FileList {0: File, length: 1}
            //    0: File {name: "风景.jpg", lastModified: 1553135747721, lastModifiedDate: Thu Mar 21 2019 10:35:47 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 27556, …}
            //    length: 1
            //    __proto__: FileList

            console.log($("#id_avatar")[0].files[0]);
            // 获取到了整个上传的文件内容
            // File {name: "风景.jpg", lastModified: 1553135747721, lastModifiedDate: Thu Mar 21 2019 10:35:47 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 27556, …}
            */

            $.ajax({
                url: "/register/",
                type: "post",
                // 当需要传输图片的时候,需要将processData和contentType设置为false
                processData: false,
                contentType: false,
                data: formData,
                success:function (data) {
                    // 这里data是后端返回的一个字典ret = {"status": 0, "msg": "/reg/"}
                    if (data.status){
                        // 有错误就展示错误
                        // console.log(data.msg);
                        // 将报错信息填写到页面上
                        $.each(data.msg, function (k,v) {
                            // console.log("id_"+k, v[0]);
                            // console.log($("#id_"+k));
                            $("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error");
                        })
                        //console.log(123)
                    }else {
                        // 没有错误就跳转到指定页面,这里data是后端返回的一个字典ret = {"status": 0, "msg": "/reg/"}
                        location.href = data.msg;
                    }
                }
            })
        });

        // 当input获取焦点的事件,移除报错的样式,并且晴空报错信息。
        $("form input").focus(function () {
            $(this).next().text("").parent().parent().removeClass("has-error");
        })

        $("#id_username").blur(function () {
            var username = $(this).val();

            $.ajax({
                url: "/check_username_exist/",
                type: "get",
                data: {"username": username},
                success: function (data) {
                    if (data.status){
                        //$("#id_username").next.text(data.msg).parentElement().parentElement().addClass("has-error");
                        // 上面为错误写法
                        $("#id_username").next().text(data.msg).parent().parent().addClass("has-error");
                    }
                }
            })
        })
    </script>
</body>
</html>
register.html

 

views.py

def register(request):
    if request.method == "POST":
        ret = {"status": 0, "msg": ""}
        form_obj = forms.RegForm(request.POST)
        # print(request.POST)
        if form_obj.is_valid():
            # 数据库中没有re_password字段,需要从字典中剔除re_password字段
            form_obj.cleaned_data.pop("re_password")
            # 接收从ajax发送过来的的图片数据
            avatar_img = request.FILES.get("avatar")
            print(avatar_img)
            models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img)
            ret["msg"] = "/reg/" # ajax在接收到ret对象后,会将这个数据取出,并且将这个数据通过使用location.href作为跳转目录
            return JsonResponse(ret)
        else:
            ret["status"] = 1
            ret["msg"] = form_obj.errors
            print(ret)
            return JsonResponse(ret)

    form_obj = forms.RegForm()
    return render(request, 'register.html', {"form_obj": form_obj})

def reg(request):
    return render(request, 'index.html') # 这里直接回复HttpResponse即可

 最后,也是最重要,添加url路由,切记切记

from django.views.static import serve
from django.conf import settings

urlpatterns = [
    re_path(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),
]