当前位置: 首页 > 编程日记 > 正文

Django 图片上传upload_to路径指定失效的问题记录

为什么80%的码农都做不了架构师?>>>   hot3.png

初始方法一:

疑虑:model使用upload_to自定义路径方法失效,指定路径也失效。最后以Views中指定MEDIA_URL和MEDIA_ROOT做拼接,并且自行判断并建立文件夹,手动chunk保存。不完美的解决。

model:    看avatar字段的upload_to

import uuid
from django.db import models
from django.contrib.auth.models import AbstractUserclass SysUser(AbstractUser):"""用户扩展表,用于替换auth的user类,并添加头像和昵称。"""uid = models.BigAutoField(primary_key=True)nickname = models.CharField(max_length=32, verbose_name="昵称")# 使用 models.ImageField 需要安装 Pillow ,cmd命令:pip install Pillowavatar = models.ImageField(verbose_name="头像", upload_to="avatar11")class Meta:# 数据库显示的表名db_table = "sys_user"

form:

from django.forms import Form
from django.forms import widgets
from django.forms import fieldsclass EditUserForm(Form):"""..."""e_avatar = fields.ImageField(required=False,widget=widgets.FileInput(attrs={"hidden": "hidden"}))"""..."""

Views:

def upload_user_avatar(request):"""用户上传头像操作"""if request.method == "POST":user_id = request.user.uid        # 只是当前登录用户ret = {'state': True, 'error': None, 'data': None}# user_id = request.POST.get("uid", None)avatar = request.FILES.get("avatar", None)# 如果文件夹不存在,则建立dir_path = os.path.join(MEDIA_ROOT, "users", "{}_{}".format(request.user.uid, request.user.username), "avatar")if not os.path.exists(os.path.join(dir_path)):os.makedirs(os.path.join(dir_path))avatar_path = os.path.join(dir_path, avatar.name)try:with open(avatar_path, 'wb+') as img:for chunk in avatar.chunks():img.write(chunk)print("文件接收成功")img_url = os.path.join("users", "{}_{}".format(request.user.uid, request.user.username), "avatar")SysUser.objects.filter(uid=user_id).update(avatar=img_url)ret["data"] = "头像更新成功"except Exception as e:ret["state"] = Falseret["data"] = "头像更新失败,请确认图片格式"print(e)return HttpResponse(json.dumps(ret))

html:

<div class="form-group text-center"><label>{# request.user.avatar  是读取实例的avatar字段,也就是不加MEDIA_URL前缀的 #}{# request.user.avatar.url  是读取实例的avatar字段了,并且添加MEDIA_URL作为前缀的 #}<img id="avatar-img" src="{{ request.user.avatar.url }}" width="200px" height="200px">{{ edit_user_form.e_avatar }}</label>
</div>

  • SysUser.objects.filter(uid=user_id).update(avatar=img_url)
  • 这句话执行结束后,只保存文件名,无法使用upload_to指定的路径。
  • 页面加载时,直接使用拼接后路径。

初始方法二:

TMD,一个保存方式的问题,竟然能啰啰嗦嗦这么久。以后以此方法操作。

model:不变

views:

def upload_user_avatar(request):"""用户上传头像操作"""if request.method == "POST":user_id = request.user.uid        # 只是当前登录用户ret = {'state': True, 'error': None, 'data': None}avatar = request.FILES.get("avatar", None)try:user_obj = SysUser.objects.filter(uid=user_id).first()user_obj.avatar = avataruser_obj.save()ret["data"] = "头像更新成功"except Exception as e:ret["state"] = Falseret["data"] = "头像更新失败,请确认图片格式"print(e)return HttpResponse(json.dumps(ret))
  • user_obj.save()
  • 使用这种保存方式的好处:
  1. 会自动保存文件路径到数据库
  2. 会自动保存文件到指定路径
  3. 必要时会自动创建目录。

目前最终方法:

model:

import uuid
import os
from django.db import models
from django.contrib.auth.models import AbstractUser
"""
python-cmd : makemigrations
python-cmd : migrate
"""def user_directory_path(instance, filename):"""用户上传文件时的自定义操作"""ext = filename.split('.')[-1]                           # 获取上传的文件名的后缀filename = '{0}.{1}'.format(uuid.uuid4().hex[:8], ext)  # 修改文件名,谨防重名。(文档说重名后,会自动增加后缀)sub_folder = 'avatar'# 日后如果对上传文件的类型进行归档时可以COPY这个做参考。# if ext.lower() in ["jpg", "png", "gif", "ico"]:#    sub_folder = "avatar"# if ext.lower() in ["pdf", "docx"]:#     sub_folder = "document"return os.path.join("users", "%s-%s" % (instance.user.uid, instance.user.username), sub_folder, filename)class SysUser(AbstractUser):"""用户扩展表,用于替换auth的user类,并添加头像和昵称。"""uid = models.BigAutoField(primary_key=True)nickname = models.CharField(max_length=32, verbose_name="昵称")# 使用 models.ImageField 需要安装 Pillow ,cmd命令:pip install Pillowavatar = models.ImageField(verbose_name="头像", upload_to=user_directory_path)class Meta:# 数据库显示的表名db_table = "sys_user"

form:

from django.forms import Form
from django.forms import widgets
from django.forms import fieldsclass EditUserForm(Form):"""..."""e_avatar = fields.ImageField(required=False,widget=widgets.FileInput(attrs={"hidden": "hidden"}))"""页面操作该元素时,使用的ajax方式,所以仅对此项进行操作。未使用EditUserForm做验证等操作。""""""..."""

views:

def upload_user_avatar(request):"""用户上传头像操作"""if request.method == "POST":user_id = request.user.uid        # 只是当前登录用户ret = {'state': True, 'error': None, 'data': None}# user_id = request.POST.get("uid", None)   # 如果以后有需求修改其他人的信息时,再从页面获取。avatar = request.FILES.get("avatar", None)try:user_obj = SysUser.objects.filter(uid=user_id).first()user_obj.avatar = avataruser_obj.save()ret["data"] = "头像更新成功"except Exception as e:ret["state"] = Falseret["data"] = "头像更新失败,请确认图片格式"print(e)return HttpResponse(json.dumps(ret))

html:

<div class="form-group text-center"><label>{# request.user.avatar  是读取实例的avatar字段,也就是不加MEDIA_URL前缀的 #}{# request.user.avatar.url  是读取实例的avatar字段了,并且添加MEDIA_URL作为前缀的 #}<img id="avatar-img" src="{{ request.user.avatar.url }}" width="200px" height="200px">{{ edit_user_form.e_avatar }}</label>
</div>

JS:

// 上传文件按钮(label里的图片)点击事件
$('#id_e_avatar').on('change',function () {// 文件上传之前在本地加载预览。{// 获取用户最后一次选择的图片var choose_file=$(this)[0].files[0];// 创建一个新的FileReader对象,用来读取文件信息var reader=new FileReader();// 读取用户上传的图片的路径reader.readAsDataURL(choose_file);// 读取完毕之后,将图片的src属性修改成用户上传的图片的本地路径reader.onload=function () {$("#avatar-img").attr("src",reader.result)}}// 使用FormData格式,将文件上传至服务器formdata = new FormData();//formdata.append('uid',$('#id_e_id').val());formdata.append("avatar",$("#id_e_avatar")[0].files[0]);$.ajax({type: "POST",url: "/account/upload_user_avatar",data:formdata,processData:false,	//上传文件时需要如此设置1contentType:false,	//上传文件时需要如此设置2success:function (data) {data = JSON.parse(data);console.log(data);alert(data.data)	// 偷懒了,哈哈}});
});

media_url映射:

from django.urls import path, re_path, include
from django.views.generic.base import RedirectView
from django.views.static import serve    # 映射media_root路径,可以通过浏览器访问的操作-1
from django.contrib.auth.decorators import login_required
from WXH_DJANGOWEB import settings
from utils.required import requiredurlpatterns = [path('account/', include("account.urls")),path('blog/', include("blog.urls")),re_path(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT, })# 映射media_url,可以通过浏览器访问的操作-2
]

至此,记录完毕。回家吃饭。坑爹的保存方式…… 愿同志们绕坑而行,用不遇坑。

转载于:https://my.oschina.net/asktao/blog/3004672

相关文章:

javascript tab切换类LixTabs最新版

javascript Tab切换类LixTabs&#xff0c;更新至0.5版: 受snandy的“读jquery”系列的启发&#xff0c;改进了代码&#xff0c;现在调用LixTabs时不用加new了。即可以这样写&#xff1a;var tab Tabs();把原来的参数evt&#xff0c;改成了易理解的event(我的疏忽)总代码量&…

linux虚拟机文件挂载

把U盘中的文件上传到linux虚拟机中&#xff0c;可以采用挂载的方式。 &#xff08;1&#xff09;启动虚拟机 &#xff08;2&#xff09;把U盘插入电脑中 &#xff08;3&#xff09;输入命令 fdisk -l可以查看新的分区 &#xff08;4&#xff09; cd /mnt mkdir usb mount /d…

HDU 1757 A Simple Math Problem

Problem Description Lele now is thinking about a simple function f(x).If x < 10 f(x) x.If x > 10 f(x) a0 * f(x-1) a1 * f(x-2) a2 * f(x-3) …… a9 * f(x-10);And ai(0<i<9) can only be 0 or 1 .Now, I will give a0 ~ a9 and two positive intege…

mariadb 内存占用优化

本文由云社区发表 作者&#xff1a;工程师小熊 摘要&#xff1a;我们在使用mariadb的时候发现有时候不能启动起来&#xff0c;在使用过程中mariadb占用的内存很大&#xff0c;在这里学习下mariadb与内存相关的配置项&#xff0c;对mariadb进行调优。 查询最高内存占用 使用以下…

windows程序设计之对话框简介1

这里先介绍下wParam和lParam&#xff0c;对于鼠标而言&#xff0c;LOWORD(wParam)和HIWORD(wParam)代表鼠标位置x,y坐标&#xff0c;对于菜单和控件而言&#xff0c;两者wParam的低字节都是各自的ID&#xff0c;即LOWORD(wParam)都是ID。两者的高字节对菜单而言是0&#xff0c;…

linux虚拟机下安装Tomcat

&#xff08;1&#xff09;首先通过挂载的方式把 tomcat的安装包从U盘上传到虚拟机中 我上传的路径是 &#xff1a;usr/tomcat &#xff08;2&#xff09; cd /usr/tomcat tar xzvf 压缩包的名字 ##进行解压&#xff08;3&#xff09;进到tomcat安装目录下的bin文件夹 ./…

unity中使用自定义shader进行光照贴图烘培无法出现透明度的坑爹问题

最近开发中在对场景进行光照贴图烘焙时发现一个坑爹问题&#xff0c;在使用自定义shader的时候&#xff0c;shader命名中必须包含Transparent路径&#xff0c;否则烘焙的时候不对alpha通道进行计算&#xff0c;烘焙出来都是狗皮膏药 比如一个shader叫 Shader "xx/UnlitAlp…

动软代码生成器教程——懒人有福了

很多时候项目必须是三层架构模式&#xff0c;但是很多繁琐的代码让多数程序员闹心……那有没有一个省时省力的工具快速的帮我们搞定三层架构呢&#xff1f;回答是肯定的&#xff0c;很早之前技术牛人李天平就开发出了这么一款工具&#xff0c;目前该工具还在不断的更新&#xf…

unity3d做简单小游戏可以吗?

可以吗&#xff1f;当然。如果是独立开发&#xff0c;主要在美工&#xff0c;这类的游戏程序简单&#xff0c;有些基础就行&#xff0c;美工要做得好可不容易&#xff0c;要是效果要求不高&#xff0c;随便在max拉几个模型吧。unity方面&#xff0c;熟悉一下&#xff0c;如果有…

逻辑覆盖测试(一)语句覆盖

语句覆盖&#xff1a; 设计测试用例时保证程序的每条语句至少执行一次。 简单来说&#xff0c;就是每个语句都覆盖一遍。 例子&#xff1a; 流程图如下&#xff1a; 测试用例如下&#xff1a; x4,z9&#xff0c;第一个if语句执行到了&#xff1b; x4,y7,第二个if语句为true…

「小程序JAVA实战」小程序的视频展示页面初始化(63)

转自&#xff1a;https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeshipinzhanshiyemianchushihua62/ 进入列表详情&#xff0c;展示点赞状态用户的名称&#xff0c;头像名称。源码&#xff1a;https://github.com/limingios/wxProgram.git 中No.15和springbo…

.NET判断字符串是否是数值型或xxx型

using System.Text.RegularExpressions; Regex digitregex new Regex("^[0-9]\d*[.]?\d*$"); if (!digitregex.IsMatch(TextBox1.Text)) { TextBox1.Text""; MessageBox.Show("只能输入数字&#xff01;","提示…

Spring.net使用说明

使用方法&#xff1a;1.在配置文件设置Spring.net 节点在配置节中&#xff0c;声明Spring.net&#xff0c;配置 context&#xff0c;objects 标签&#xff0c;来源&#xff08;type&#xff09;<!--配置节&#xff1a;主要用来 配置 asp.net框架之外的 标签&#xff0c;告诉…

逻辑覆盖测试(三)条件覆盖

条件覆盖&#xff1a;设计测试用例时应保证程序中每个复合判定表达式中&#xff0c;每个简单判定条件的取真和取假情况至少执行一次。 例子&#xff1a; 流程图&#xff1a; 测试用例&#xff1a; 程序中一共两个if语句&#xff0c;都是复合判定条件&#xff0c;其中的简单…

Linux UserSpace Back-Door、Rootkit SSH/PAM Backdoor Attack And Defensive Tchnology

catalog 0. 引言 1. Pam后门 2. SSH后门 3. Hijacking SSH 4. Hijacking SSH By Setup A Tunnel Which Allows Multiple Sessions Over The Same SSH Connection Without Re-Authentication 5. Hijacking Active SSH Screen Sessions 0. 引言 0x1: 安全攻防观点 1. Know Your …

澳大利亚多地热浪来袭 最高温度超40摄氏度

中新网1月24日电 据澳洲网报道&#xff0c;近日&#xff0c;澳大利亚多地热浪来袭&#xff0c;其中&#xff0c;南澳和维州的部分地区气温将飙升至40摄氏度以上。维州政府发布声明&#xff0c;提醒民众做好应对高温天气的准备。资料图&#xff1a;当地时间1月21日&#xff0c;澳…

Multithread 之 introduction

Why multithreading?&#xff08;摘自《win32 多线程程序设计》&#xff09;单线程程序就像超级市场中唯一的一位出纳&#xff0c;这个出纳对于小量采购可以快速结账。但如果有人采购了一大车货品&#xff0c;结账就需要点时间了&#xff0c;其他每个人都必须等待。多线程程序…

逻辑覆盖测试(四)判定/条件覆盖

判定/条件覆盖&#xff1a;测试用例的设计应满足判定节点的取真和取假分支至少执行一次&#xff0c;且每个简单判定条件的取真和取假情况也至少执行一次。 简单来说&#xff0c;就是判定覆盖和条件覆盖取交集。 例子&#xff1a; 流程图&#xff1a; 当判定覆盖和条件覆盖…

jQuery选择器的工作原理和优化

至于有那些选择器&#xff0c;在帮助手册中都有&#xff0c;自己去看&#xff0c;这篇主要是分析他的工作原理&#xff0c;而优化我们写 的选择器&#xff0c;尤其在页面内容很多的情况下&#xff0c;更应该需要优化。下边就言归正传。 每次申明一个jQuery对象的时候&#xff0…

webservice发送字符串

假设只是发送一个字符串client&#xff0c;这是很easy&#xff0c;只需要输入xfire包&#xff0c;编写接口&#xff0c;编写的实现方法。变化。 假设你要传输的数组或自定义类。到用于接口准备的需要agexis文件。更复杂。 尝试传输这些假设没有成功。在发送成功的字符串&#x…

600余名外出务工者免费乘高铁“返乡专列”回云南过春节

中新网昆明1月25日电(缪超)记者25日从中国铁路昆明局集团获悉&#xff0c;云南与广东两省人社部门近日组织开行高铁“返乡专列”&#xff0c;免费安排600多名云南籍外出务工人员乘坐高铁动车返乡过春节。图为志愿者与乘务员为外出务工人员精心准备的歌舞节目。中国铁路昆明局集…

逻辑覆盖测试(六)--路径测试

路径覆盖&#xff1a;设计足够多的测试用例&#xff0c;使得程序中所有可能的路径都被至少被执行一次。 例子&#xff1a; 测试用例&#xff1a; 思路&#xff1a; 先是都经过a&#xff0c;到一个if分支&#xff0c;可以有a 、b和 a、c&#xff0c;然后到第二个if分支&#…

浅谈MVP设计模式

最近公司在做一个医疗项目&#xff0c;使用WinForm界面作为客户端交互界面。在整个客户端解决方案中。使用了MVP模式实现。由于之前没有接触过该设计模式&#xff0c;所以在项目完成到某个阶段时&#xff0c;将使用MVP的体会写在博客里面。 所谓的MVP指的是Model&#xff0c;Vi…

C#委托与事件

之前写过一篇关于C#委托与事件的文章&#xff08;见《C#委托和事件例析》&#xff09;&#xff0c;不过还是收到一些网友的提问。所以&#xff0c;今天再换另一个角度来详解一下这个问题。 一、在控制台下使用委托和事件 我们都知道&#xff0c;C#中有“接口”这个概念&#xf…

Docker for mac安装

Mac安装Docker docker下载地址: https://hub.docker.com/editions/community/docker-ce-desktop-mac docker for mac document: https://docs.docker.com/docker-for-mac/ 系统要求 Docker Desktop - Mac适用于OS X Sierra 10.12和更新的macOS版本。 获得Docker 稳定边缘Stable…

白盒测试--基本路径测试法

1.为什么要有基本路径测试法&#xff1f; 对于路径测试&#xff0c;最理想的情况是路径全部覆盖&#xff0c;单对于复杂的大程序要做到路径覆盖是不可能的&#xff0c;因此可以采用基本路径测试。 2.基本路径测试法的步骤&#xff1f; &#xff08;1&#xff09;画出程序的控制…

Postmortem报告

1. 每个成员在beta 阶段的实践和alpha 阶段有何改进? 2. 团队在beta 阶段吸取了那些alpha 阶段的经验教训? 在alpha阶段中&#xff0c;虽然我们团队已经对软件主要功能核心代码完成了&#xff0c;但是由于我们团队现有掌握有关于安卓开发的技术并不成熟&#xff0c;无法对软件…

是否可以人为修改发表时间

是否可以人为修改发表时间转载于:https://blog.51cto.com/14188306/2346747

关于win7_iis报500.19和500.21错误的解决方法

关于win7_iis报500.19和500.21错误的解决方法HTTP 错误 500.19 Internal Server Error的解决方法WIN7下.Net开发遇到的又一问题&#xff1a;HTTP 错误 500.19 - Internal Server Error&#xff0c;无法访问请求的页面&#xff0c;因为该页的相关配置数据无效。详细错误信息模块…

黑盒测试--因果图法

例子&#xff1a; (1)根据题目可以得到原因和结果分别是&#xff1a; &#xff08;2&#xff09;画出因果图 根据题意来画因果图&#xff0c;输入第一个字符是A或B要写成一个状态&#xff0c;且第二个字符为数字。 画因果图主要就是理清不同状态之间的关系&#xff0c;还有有…