目录
1. 利用form表单上传文件
2. ajax上传文件
3. 上传头像时预览头像
4. 头像存储至数据库
头像存储的路径
访问上传的图片
models.py中avatar字段方法
urls.py加入url(r'^fileput/', views.fileput),
1. 利用form表单上传文件
模版文件fileput.html:
{# 传文件必须用form-data这种类型#}
注意:form标签默认enctype="application/x-www-form-urlencoded",而上传文件时,必须设定enctype="multipart/form-data",否则服务端取不到文件对象。input标签的type='file'
视图文件views.py
def fileput(req):
if request.method == 'POST':
print(request.POST) #
print(request.FILES) #文件对象 ]}>
file_obj = request.FILES.get('myfile')
print(file_obj.name) # 打印文件名
with open(file_obj.name,'wb') as f: #默认写在项目根目录下
for line in file_obj:
f.write(line)
return render(req,'fileput.html')
注意: request.FILES是一个字典类型的数据,key是前端input标签的name值,值就是前端上传的文件对象。
file_obj = request.FILES.get('myfile')
//获取文件对象file_name = file_obj.name
//获取文件名称
文件是以二进制的方式传递到后端的,所以将上传的文件写入到服务端本地时,直接用wb模式
2. ajax上传文件
模版文件fileput.html
Title
{# 传文件必须用form-data这种类型#}
注意:
var formdata = new FormData();
是JS语法,实例化出来的对象是一个类似python字典一样的容器,可以传大文件;$('[name="myfile"]')[0].files[0])
可以取到存储在中的文件对象,文件对象中包含以下图中的内容:
- processData默认值是true,contentType默认值是x-www-form-urlencoded,这个配置的意义是,当processData的值为true时,就将数据预处理成contentType设定的类型,contentType:"x-www-form-urlencoded"会将数据处理成这样“?a=1&b=2”发送至后端,当没有写processData和contentType时,浏览器默认processData为ture,contentType为'x-www-form-urlencoded'。
特别注意:利用ajax上传文件时,必须将processData设置为false,contentType设置为false。也就是不对数据做预处理。否则前端jquery会报错。
视图文件views.py:
def fileput(request):
if request.is_ajax(): #判断是不是ajax请求
print(request.POST)
file_obj = request.FILES.get('imgFile')
imgpath = r'./blog/static/images/'
print(file_obj.name)
filepath = os.path.join(imgpath,file_obj.name)
with open(filepath,'wb') as f: #将上传的文件写到指定路径
for line in file_obj:
f.write(line)
return HttpResponse('上传成功')
return render(request,'fileput.html')
3. 上传头像时预览头像
模版html文件上传头像的部分代码内容如下:
注意:头像预览功能原理时,点击上传文件后选择了图片后,就将img标签的src路径换成被选择的图片本地路径,不能使用点击事件(onclick),应该使用onchange事件(jquery中是change事件),当标签发生改变时才触发。
4. 头像存储至数据库
头像存储的路径
models.py中的UserInfo类中的avatar字段设置:
class UserInfo(Form):
...
avatar = models.FileField(verbose_name='头像', upload_to='avatar/', default="avatar/default.png")
...其他字段省略
数据库中存储头像的字段avatar,实际存储的是这个头像文件的相对路径,是通过UserInfo表中avatar字段的upload_to参数的值+文件名:即avatar/a.png。django会在项目根目录下创建一个名为avatar的目录,将文件存至avatar目录下。
当settings.py中配置了
# 用户上传的文件路径配置
MEDIA_URL = '/media/' # 是MEDIA_ROOT的别名
MEDIA_ROOT = os.path.join(BASE_DIR,'blog','media') #在blog应用下创建一个media目录
django就会自动在MEDIA_ROOT目录下创建一个avatar目录,然后将文件存至此目录下,真实文件存储的绝对路径:MEDIA_ROOT+upload_to+文件名。假如项目名称为myblog,那文件存储的真实路径为:./myblog/blog/media/avatar/a.png
访问上传的图片
假设用户上传了一个图片:a.jpg
如果settings.py中设置了MEDIA_URL="/media/",访问时应该写的路径为:/media/avatar/a.jpg
要想在前端页面直接访问用户上传的文件,还需要配置一条url,urls.py添加如下:
# 必须先导入如下模块
from django.views.static import serve
from myblog import settings
urlpatterns = [
#... 省略部分配置 ...
# 添加media 配置
url(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
前端上传头像后,后端视图函数views.py存入数据库:
def register(req):
form = RegistForm()
if req.method == 'POST':
response = {'status': True, 'msg': None, 'query': None}
form = RegistForm(req.POST)
if form.is_valid():
valid_code = form.cleaned_data['valid']
if valid_code.upper() == req.session['valid_code'].upper():
form.cleaned_data.pop('password_confirm')
form.cleaned_data.pop('valid') # 验证码和确认密码不需要存入数据库,所以需要从干净数据中去除掉。
avatar = req.FILES.get('avatar') # 从前端获取上传的文件对象
form.cleaned_data['avatar'] = avatar
# 将文件对象加入到干净数据中,以便写入到数据库中;\
# django会根据models.py中的UserInfo类下的avatar字段的upload_to参数设定的目录名,创建一个目录,\
# 然后把这个文件对象存至这个目录下,数据库中存的是这个文件的相对路径
user = UserInfo.objects.create_user(**form.cleaned_data)
if user:
response['username'] = form.cleaned_data['username']
else:
response['status'] = False
response['query'] = '验证码错误'
else:
response['status'] = False
response['msg'] = form.errors
return HttpResponse(json.dumps(response))
return render(req,'register.html',locals())
models.py中avatar字段方法
user = UserInfo.objects.get(nid=1)
print('avatar_type:',user.avatar,type(user.avatar))
print('URL:',user.avatar.url)
print('PATH:',user.avatar.path)
print('NAME:',user.avatar.name)
print('SIZE:',user.avatar.size)
以上输出的结果:
avatar_type: avatar/meinv.jpg
URL: /media/avatar/meinv.jpg
PATH: E:\python\python_study\day22\myblog\blog\media\avatar\meinv.jpg
NAME: avatar/meinv.jpg
SIZE: 5241