python做一个网页、让用户上传数据_Django项目实战之用户头像上传与访问的示例...

本文详细介绍了如何使用Django实现用户头像上传并存储到服务器本地或数据库,包括HTML表单、URL配置、视图函数、模型创建等步骤,并探讨了文件上传的原理和注意事项,如CSRF验证、文件命名冲突处理、AJAX提交以及预览功能的实现。
摘要由CSDN通过智能技术生成

1 将文件保存到服务器本地

upload.html

{% csrf_token %}

用户名:
头像

urls.py

from django.conf.urls import url

from app01 import views

urlpatterns = [

url(r'^upload',views.upload)

]

views.py

from django.shortcuts import render,HttpResponse

def upload(request):

if request.method == 'POST':

name = request.POST.get('username')

avatar = request.FILES.get('avatar')

with open(avatar.name,'wb') as f:

for line in avatar:

f.write(line)

return HttpResponse('ok')

return render(request,'upload.html')

总结

这样,我们就做好了一个基本的文件上传小示例,这里需要注意的有几点:

1.form表单里需要加上csrf_token验证

2.文件的input框的type的值为file

3.在视图函数中获取文件要用request.FILES.get()方法

4.通过obj.name可以获取文件的名字

2 将文件上传到数据库

models.py

from django.db import models

class User(models.Model):

username = models.CharField(max_length=16)

avatar = models.FileField(upload_to='avatar')

views.py

def upload(request):

if request.method == 'POST':

name = request.POST.get('username')

avatar = request.FILES.get('avatar')

models.User.objects.create(username=name,avatar=avatar)

return HttpResponse('ok')

return render(request,'upload.html')

总结

上面已经实现了将文件上传到数据库的功能,需要注意的有几点:

1.所谓的上传到数据库,不是讲图片本身或者二进制码放在数据库,实际上也是将文件上传到服务器本地,数据库只是存了一个文件的路径,这样用户要调用文件的时候就可以通过路径去服务器指定的位置找了

2.创建ORM的时候,avatar字段要有一个upload_to=''的属性,指定上传后的文件放在哪里

3.往数据库添加的时候,文件字段属性赋值跟普通字段在形式上是一样的,如:models.User.objects.create(username=name,avatar=avatar)

4.如果有两个用户上传的文件名重复,系统会自动将文件改名,效果如下:

6e9eb70a8b2a01dfdb315ea58d58dd2a.png

附加

功能我们是实现了,看起来我们在调用文件的时候,只需要通过数据库文件路径已经保存的文件本身就可以访问图片,让它出现在网页上,其实并不是这样,

我们需要配置一些东西,django才可以找的到,不然的话就会过不了urls验证,而我们之所以可以直接访问static里的静态文件,是因为django已经帮我们配置好了。

1fd189f2a59edbf1e1007f778a556f31.png

配置步骤如下:

1、在站点的setting.py里配置

MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media") #blog是项目名,media是约定成俗的文件夹名

MEDIA_URL="/media/" # 跟STATIC_URL类似,指定用户可以通过这个路径找到文件

2、在urls.py里配置

from django.views.static import serve

from upload import settings #upload是站点名

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

配置完后,就可以通过http://127.0.0.1:8001/media/milk.png访问到图片了

3 用AJAX提交文件

upload.html

{% csrf_token %}

用户名:
头像

$('#submit-btn').on('click',function () {

formdata = new FormData();

formdata.append('username',$('#name-input').val());

formdata.append("avatar",$("#avatar")[0].files[0]);

formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());

$.ajax({

processData:false,contentType:false,url:'/upload', type:'post', data:formdata,success:function (arg)

{

if (arg.state == 1){ alert('成功!') }

else { alert('失败!') } } }) });

views.py

from django.shortcuts import render,HttpResponse

from django.http import JsonResponse

from app01 import models

def upload(request):

if request.method == 'POST':

name = request.POST.get('username')

avatar = request.FILES.get('avatar')

try:

models.User.objects.create(username=name,avatar=avatar)

data = {'state':1}

except:

data = {'state':0}

return JsonResponse(data)

return render(request,'upload.html')

总结

1.Ajax上传的时候,按钮的tpye一定不要用submit

2.Ajax上传的时候data参数的值不再是一个普通‘字典'类型的值,而是一个FormData对像

创建对象formdata = new FormData();

往里面添加值formdata.append('username',$('#name-input').val());

3.Ajax在做post提交的时候要加上csrf验证

formdata.append("csrfmiddlewaretoken",$("[name='csrfmiddlewaretoken']").val());

4.最后,Ajax上传文件的时候要有两个参数设置

processData:false

contentType:false

4 上传图片文件的时候有预览功能

default.png

头像

// 上传文件按钮(label里的图片)点击事件

$('#avatar-input').on('change',function () {

// 获取用户最后一次选择的图片

var choose_file=$(this)[0].files[0];

// 创建一个新的FileReader对象,用来读取文件信息

var reader=new FileReader();

// 读取用户上传的图片的路径

reader.readAsDataURL(choose_file);

// 读取完毕之后,将图片的src属性修改成用户上传的图片的本地路径

reader.οnlοad=function () {

$("#avatar-img").attr("src",reader.result)

}

});

5 大总结

对于文件上传,不管是直接form提交也好,Ajax提交也好,根本问题是要告诉浏览器你要上传的是一个文件而不是普通的字符串

而怎么样告诉浏览器呢,就是通过请求体重的ContentType参数,我们上传普通的字符串的时候不用指定,因为它有默认值,

而如果要传文件的话,就要另外指定了。总结以下几点

1.form表单上传的话是通过 enctype="multipart/form-data" 来指定ContentType

2.ajax上传的话是通过  processData:false 和 contentType:false来指定ContentType

3.form上传的时候,文件数据是通过标签来‘'包裹‘'数据,

4.ajax上传的时候,是通过一个 FormData 实例对象来添加数据,传递的时候传递这个对象就行了

5.数据传递过去之后,是封装在request.FILES里,而不是request.POST里

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值