头像的上传的实现

  上传头像跟上传文件一样,但是平时的应用中,我们都是直接点击一张图片,就会跳出类似于input标签中type为file的样式,这个实现就用到了label标签的特性,通过label标签的关联特性,我们可以将一张图片包在label标签中,并且将input标签隐藏掉,就可以实现点击图片,打开的是input的标签。

具体代码的实现:(基于bootstrap的实现)

<div>
<label class="col-sm-2 control-label">头像</label>
<
div class="col-sm-8"> <label for="id_avatar"><img src="/static/avatars/default.png" alt="图像加载失败"></label> <input type="file" id="id_avatar" name="file" style="display:none"> </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" alt=""></label>
                        <input accept="image/*" type="file" name="avatar" id="id_avatar" style="display: none">
                        <span class="help-block"></span>
                    </div>
 </div>

             
<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
    // 找到头像的input标签绑定change事件
    $("#id_avatar").change(function () {
        // 1. 创建一个读取文件的对象
        var fileReader = new FileReader();
        // 取到当前选中的头像文件
        // console.log(this.files[0]);
        // 读取你选中的那个文件
        fileReader.readAsDataURL(this.files[0]);  // 读取文件是需要时间的
        fileReader.onload = function () {
            // 2. 等上一步读完文件之后才 把图片加载到img标签中
            $("#avatar-img").attr("src", fileReader.result);
        };
    });

备注:

  文件的读取是需要时间的,所以必须使用onload方法进行等待文件的读取完成

  此外,使用this.files得到的是一个对象,取0得到的是这个文件。

  我们也可以在输入文件的那个input框中添加一个属性:accept 比如accept="image/png",表示一个默认的格式。

预览功能实现后,当用户确认选择,进行上传时,就需要进行后端的存储操作

备注:使用form表单进行向后端的提交带文件的数据时,需要指定form表单的提交属性  在form表单中加上enctype属性 enctype=multipart/form-data,同样的使用ajax向后端提交带文件的数据时也需要类似的属性:1.添加两个属性processData:false,contentType:false   2.data必须是FormData()类型

以Django为例,使用ajax实现向后端的提交

ajax代码实现:

 // AJAX提交注册的数据
    $("#reg-submit").click(function () {
        // 取到用户填写的注册数据,向后端发送AJAX请求
        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());
        formData.append("avatar", $("#id_avatar")[0].files[0]);
        formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());

        $.ajax({
            url: "/reg/",
            type: "post",
            processData: false,
            contentType: false,
            data: formData,
            success:function (data) {
                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");
                    })

                }else {
                    // 没有错误就跳转到指定页面
                    location.href = data.msg;
                }
            }
        })
    });

    // 将所有的input框绑定获取焦点的事件,将所有的错误信息清空
    $("form input").focus(function () {
        $(this).next().text("").parent().parent().removeClass("has-error");
    })

视图函数部分的实现:

# 注册的视图函数
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():
            # 校验通过,去数据库创建一个新的用户
            form_obj.cleaned_data.pop("re_password")
            avatar_img = request.FILES.get("avatar")
            models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img)
            ret["msg"] = "/index/"
            return JsonResponse(ret)
        else:
            print(form_obj.errors)
            ret["status"] = 1
            ret["msg"] = form_obj.errors
            print(ret)
            print("=" * 120)
            return JsonResponse(ret)
    # 生成一个form对象
    form_obj = forms.RegForm()
    print(form_obj.fields)
    return render(request, "register.html", {"form_obj": form_obj})

 备注:上传的文件名有重复时,Django内部会自动在文件名后加一个随机的字符串做区分,并在数据库存储。

另外,在Django中我们用到了form组件的一些用法

from django import forms
from blog import models
from django.core.exceptions import ValidationError

# from django.core.validators import RegexValidator
# mobile = forms.CharField(validators=[RegexValidator('regex','哈哈哈')])
class RegForm(forms.Form):
    username=forms.CharField(label='用户名',max_length=12,error_messages={'required':'不能为空'},widget=forms.widgets.TextInput(attrs={'class':'form-control','placeholder':'请输入用户名'}))
    password = forms.CharField(label='密码',min_length=6,error_messages={'min_length':'密码最少为六位','required':'不能为空'},widget=forms.widgets.PasswordInput(attrs={'class':'form-control','placeholder':'请输入密码'}))
    re_password = forms.CharField(label='确认密码',min_length=6,error_messages={'min_length':'确认密码最少为六位','required':'不能为空'},widget=forms.widgets.PasswordInput(attrs={'class':'form-control','placeholder':'请输入确认密码'}))
    email = forms.EmailField(label='邮箱',error_messages={'required':'不能为空','invalid':'格式错误'},widget=forms.widgets.EmailInput(attrs={'class':'form-control','placeholder':'请输入邮箱'}))
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if re_password:
            if password !=re_password:
                self.add_error('re_password',ValidationError('两次密码不一致'))
            else:
                self.cleaned_data.pop('re_password')
        return self.cleaned_data
    def clean_username(self):
        username = self.cleaned_data.get('username')
        is_exists = models.UserInfo.objects.filter(username=username)
        if is_exists:
            self.add_error('username',ValidationError('用户名已存在'))
        return username

    def clean_email(self):
        email = self.cleaned_data.get('email')
        is_exist = models.UserInfo.objects.filter(email=email)
        if is_exist:
            self.add_error('email',ValidationError('邮箱已存在'))
        else:
            return email

备注:label标签的特殊用法:

<!--label的两种用法-->

<!--用法一:正常用法  实现关联-->
<label for="d1">用户:</label>
<input type="text" id="d1">

<!--用法二:将input标签包到label标签里面也可以实现联动效果-->
<label>用户名 <input type="text"></label>

 用户上传的文件,Django都叫media文件

如果要在页面中展示出头像,如果上传文件的路径在static目录下,就会在页面展示出来,否则,就无法展示,因为settings.py 文件中没有设置文件访问路径。

如下图:这样配置上传文件的路径,就可以直接在页面中展示出来

如果放在了其他路径下,就要一些相应的配置

Django给我们提供了这种功能,只需要配置好media就可以

1. settings.py中:

#BASE_DIR是Django中的项目的绝对路径
#只需要在settings中添加这些就可以
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR,'media')

2.路由  urls.py 中的配置:

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


#在路由中添加路径

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

猜你喜欢

转载自www.cnblogs.com/zhaopanpan/p/9080278.html
今日推荐