一 普通上传方式
1 views
1 def upload(request):
2 if request.method == "POST":
3 # print(request.POST)
4 # print(request.FILES)
5 # 从上传的文件数据中拿到 avatar对应的文件对象
6 file_obj = request.FILES.get("avatar")
7 # 在服务端新建一个和上传文件同名的新文件
8 with open(file_obj.name, "wb") as f:
9 # 从上传文件对象中一点一点读数据
10 for i in file_obj:
11 # 写入服务端新建的文件
12 f.write(i)
13 return HttpResponse("OK")
14 return render(request, "upload.html")
2 html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
上传头像:
<input type="file" name="avatar">
</p>
<input type="submit" value="提交">
</form>
</body>
</html>
二 ajax上传方式
1 views.py
# ajax_upload上传
def ajax_upload(request):
if request.method == "POST":
# print(request.POST)
# print(request.FILES)
# 从上传的文件数据中拿到 avatar对应的文件对象
file_obj = request.FILES.get("avatar")
# 在服务端新建一个和上传文件同名的新文件
with open(file_obj.name, "wb") as f:
# 从上传文件对象中一点一点读数据
for i in file_obj:
# 写入服务端新建的文件
f.write(i)
return HttpResponse("OK")
return render(request, "ajax_upload.html")
2 html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax上传文件</title>
</head>
<body>
<input type="file" name="avatar" id="i1">
<input type="button" value="上传" id="b1">
{% csrf_token %}
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
$("#b1").click(function () {
// 先生成一个FormData对象
// 将要提交的数据 append 到FormData对象中
var fd = new FormData();
fd.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
fd.append("avatar", $("#i1")[0].files[0]); // 获取文件名字
$.ajax({
url: "/ajax_upload/",
type: "post",
data: fd,
contentType: false,
processData: false,
success: function (res) {
console.log(res)
}
})
});
</script>
</body>
</html>
三 如何注册的时候上传头像并显示
1 urls配置:
from django.views.static import serve # 用户上传文件用的模块
from django.conf import settings # 同样是上传用的
url(r'^media/(?P<path>.*)', serve, {"document_root": settings.MEDIA_ROOT}),
2 setting.py
# 告诉djanjo项目用户上传的文件保存在哪个目录下
MEDIA_ROOT = os.path.join(BASE_DIR, "upload")
# 告诉用户用哪个前缀来访问刚才的定义的那个目录别名
MEDIA_URL = "/media/"
3 views配置:
1 class RegisterView(views.View):
2 '''
3 如果是get请求,就返回注册页面,用的form写的注册页面,先导入刚才写的forms模块,然后调用RggisterForm
4 如果是post请求(就是提交请求),form_obj获取到用户填的所有内容,然后去校验数据格式是否正确,如果没问题,就去
5 数据库里面创建数据,创建之前,要先删除re_password这个字段,因为数据库里没有这个字段
6 然后接受头像文件,需要用request.FILES,去获取
7 最后去数据库保存,需要把你的普通数据和头像数据分开来存储。
8 注册成功之后,就跳转到登录界面,否则就报报错信息返回到页面上面
9 '''
10
11 def get(self, request):
12 form_obj = forms.RegisterForm()
13 return render(request, "register.html", locals())
14
15 def post(self, request):
16 res = {"code": 0}
17 form_obj = forms.RegisterForm(request.POST)
18 if form_obj.is_valid():
19 # 数据没问题,去数据库创建记录
20 form_obj.cleaned_data.pop("re_password")
21 # 头像数据,文件对象
22 avatar_obj = request.FILES.get("avatar")
23 # 头像文件保存到数据库,如果你的models里面写的这个字段FileField,就会自动写在服务器上面
24 models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_obj)
25 res["url"] = "/login/"
26 else:
27 # 数据有问题
28 res["code"] = 1
29 res["error"] = form_obj.errors
30 return JsonResponse(res)
4 html配置;
register.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>注册</title>
6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.min.css">
7 </head>
8 <body>
9 <div class="container">
10 <div class="row">
11 <div class="col-md-6 col-md-offset-3">
12 <form class="register-form">
13 {% csrf_token %}
14 {% for field in form_obj %}
15 <div class="form-group">
16 <label for="{{ field.id_for_label }}">{{ field.label }}</label>
17 {{ field }}
18 <span class="help-block"></span>
19
20
21 </div>
22 {% endfor %}
23 <div class="form-group">
24 <label for="id_avatar">头像
25 <img src="/static/images/default.png" id="avatar-img" style="width: 60px">
26 </label>
27 <input type="file" id="id_avatar" accept="image/*" class="form-control" style="display: none">
28
29 </div>
30 <div style="text-align: center">
31 <button style="width: 100px" type="button" class="btn btn-success" id="submit-btn">提交</button>
32
33 </div>
34
35 </form>
36 </div>
37 </div>
38
39 </div>
40 <script src="/static/plugins/jquery-3.3.1.min.js"></script>
41 <script src="/static/plugins/bootstrap-3.3.7/js/bootstrap.min.js"></script>
42 <script src="/static/js/register.js"></script>
43
44 </body>
45 </html>
js配置:
1 // 设置错误提示
2 $("#submit-btn").click(function () {
3 // 因为注册功能有头像文件 数据,所以要用FormData对象提交数据
4 var fd = new FormData();
5 fd.append("username", $("#id_username").val());
6 fd.append("password", $("#id_password").val());
7 fd.append("re_password", $("#id_re_password").val());
8 fd.append("phone", $("#id_phone").val());
9 fd.append("email", $("#id_email").val());
10 fd.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
11 // avatar头像
12 fd.append("avatar", $("#id_avatar")[0].files[0]);
13 $.ajax({
14 url: "/register/",
15 type: "post",
16 data: fd,
17 contentType: false,
18 processData: false,
19 success: function (res) {
20 if (res.code === 1) {
21 $.each(res.error, function (k, v) {
22 console.log(k, v[0]);
23 {
24 // #先找到input标签,下面的那个标签,然后设置错误信息,再找到显示错误标签的父标签,设置has - error
25
26 }
27 $("#id_" + k).next().text(v[0]).parent().addClass("has-error");
28 })
29 } else {
30 location.href = res.url
31 }
32
33 }
34 })
35
36 });
37
38 // 给input标签绑定获取焦点就删除错误提示的动作
39 $(".register-form input").focus(function () {
40 $(this).next().text("").parent().removeClass("has-error");
41 });
42
43 //头像预览功能
44 //值发生变化了
45 $("#id_avatar").change(function () {
46 // 取到用户选中的头像文件
47 var fileObj = this.files[0]; //路径
48 // 新建一个FileReader对象,从本地磁盘加载文件数据
49 var fr = new FileReader();
50 fr.readAsDataURL(fileObj);
51 // 读取文件是需要时间的
52 fr.onload = function () {
53 // 找到头像预览的img标签,把它的src属性设置成我读取的用户选中的图片
54 $("#avatar-img").attr("src", fr.result) //结果
55 }
56
57 });
index.html首页导航条图像显示
<li><img style="height: 40px;width: 40px;border-radius: 50%" src="/media/{{ request.user.avatar }}"></li>