Python 上传_到值更改photo.name属性
为什么Python 上传_到值更改photo.name属性,python,django,Python,Django,为什么upload\u tovalue会更改photo.name的值?我试图在运行时创建一个相册目录,并在相应的相册目录中讲述我的图像。“我的代码”可以使用适当的相册名称创建一个目录,其中包含正确的照片,但它会将self.photo.name更改为upload\u to值 如下图所示。通过管理界面,我创建了一个名为test4的相册,并选择上传tumblr\u nh09woLkmb1sfie3io1\u 1289.jpgself.photo.name的值为test4/tumblr\u nh09wo
upload\u to
value会更改photo.name
的值?我试图在运行时创建一个相册目录,并在相应的相册目录中讲述我的图像。“我的代码”可以使用适当的相册名称创建一个目录,其中包含正确的照片,但它会将self.photo.name
更改为upload\u to
值
如下图所示。通过管理界面,我创建了一个名为test4
的相册,并选择上传tumblr\u nh09woLkmb1sfie3io1\u 1289.jpg
self.photo.name
的值为test4/tumblr\u nh09woLkmb1sfie3io1\u 1289.jpg
在我的上传路径中,我也尝试了
return instance.album.title
return '/' + instance.album.title
return instance.album.title + '/'
这不会创建一个名为instance.album.title
的目录,而是用upload\u path
方法返回的文件名保存在我的MEDIA\u ROOT
中。不是实际的文件名
我觉得预期的self.photo.name应该是上传照片的名称。在这种情况下tumblr\u nh09woLkmb1sfie3io1\u 1289.jpg
from django.db import models
from django.contrib import admin
from PIL import Image
from django.conf import settings
import os.path
from django.utils.html import format_html
from django.core.files.storage import FileSystemStorage
import re
class Album(models.Model):
title = models.CharField(max_length=50, unique=True)
def __str__(self):
return self.title
def images(self):
lst = [x.photo for x in self.photo_set.all()]
return lst
def save(self, *args, **kwargs):
# super(Album, self).save(*args, **kwargs)
rgx = re.search(r'.*\w', self.title)
self.title = rgx.group(0).replace(" ", "_")
super(Album, self).save(*args, **kwargs)
class AlbumAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["images"]
def upload_path(instance, filename):
if " " in instance.album.title:
instance.album.title.replace(" ", "_")
return '/'.join([instance.album.title, filename])
class Photo(models.Model):
title = models.CharField(max_length=50, blank=True)
album = models.ForeignKey(Album)
photo = models.ImageField(upload_to=upload_path)
upload = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
def size(self):
return "%s x %s" % (self.photo.width, self.photo.height)
def thumbnail(self):
thumbnail_html = "<a href=\"{0}{1}\"><img border=\"0\" alt=\"\" src=\"{2}{3}\" height=\"40\" /></a>".format(settings.MEDIA_URL, self.photo.name, settings.MEDIA_URL, self.photo.name)
print settings.MEDIA_URL, settings.MEDIA_ROOT
return thumbnail_html
thumbnail.allow_tags = True
class PhotoAdmin(admin.ModelAdmin):
search_fields = ["title", "photo"]
list_display = ["photo", "thumbnail", "title", "album", "size"]
list_filter = ["album"]
来自django.db导入模型的
从django.contrib导入管理
从PIL导入图像
从django.conf导入设置
导入操作系统路径
从django.utils.html导入格式\u html
从django.core.files.storage导入文件系统存储
进口稀土
班级相册(models.Model):
title=models.CharField(最大长度=50,唯一性=True)
定义(自我):
返回自己的标题
def图像(自我):
lst=[x.photo for x in self.photo_set.all()]
返回lst
def保存(自身、*args、**kwargs):
#超级(相册,自我)。保存(*args,**kwargs)
rgx=re.search(r'.*\w',self.title)
self.title=rgx.group(0)。替换(“,”)
超级(相册,自我)。保存(*args,**kwargs)
类AlbumAdmin(admin.ModelAdmin):
搜索_字段=[“标题”]
列表显示=[“图像”]
def上传路径(实例,文件名):
如果instance.album.title中有“”:
instance.album.title.replace(“,”)
返回“/”.join([instance.album.title,filename])
班级照片(模特。模特):
title=models.CharField(最大长度=50,空白=True)
相册=型号。外键(相册)
照片=模型.ImageField(上传到=上传路径)
upload=models.DateTimeField(auto\u now\u add=True)
定义(自我):
返回自己的标题
def大小(自身):
返回“%s x%s”%(self.photo.width、self.photo.height)
def缩略图(自身):
缩略图_html=”“.格式(settings.MEDIA_URL、self.photo.name、settings.MEDIA_URL、self.photo.name)
打印设置.MEDIA\u URL,设置.MEDIA\u根目录
返回缩略图
thumboil.allow_tags=True
类PhotoAdmin(admin.ModelAdmin):
搜索字段=[“标题”,“照片”]
列表显示=[“照片”、“缩略图”、“标题”、“相册”、“大小”]
列表过滤器=[“相册”]
来自Django docs(),关于上传到
功能
一个本地文件系统路径,将附加到媒体根设置中,以确定url属性的值
因此,如果将
upload\u to
指定为函数,Django将尝试将文件名保存为媒体根目录的相对路径 这里是您的设置:
MEDIA_ROOT = os.path.join(BASE_DIR, "../media_root/Boothie/pics")
MEDIA_URL = '/media/'
因此,每当您将路径或函数传递给upload\u to
文件字段或ImageField
时,它将以string\u passed\u upload\u to/filename.ext或传递给它的函数生成的全名的格式保存在数据库中。通过这种方式,可以重新创建文件的完整路径:MEDIA\u ROOT+instance.photo.name
以及url:MEDIA\u url+instance.photo.name
。这不是django的确切代码,只是给你一个想法。这有意义吗?我可以用一些例子来详细说明
编辑
如果您想只获取基本文件名,可以执行os.path.split(photo.name)[1]
。但无论如何,FileField都会将文件名存储在与媒体根路径相关的数据库中。
您还可以签出应用程序,它具有该属性集,因此如果您有模型:
from smartfields import fields
def upload_path(instance, filename):
if " " in instance.album.title:
instance.album.title.replace(" ", "_")
return '/'.join([instance.album.title, filename])
class Photo(models.Model):
title = models.CharField(max_length=50, blank=True)
album = models.ForeignKey(Album)
photo = fields.ImageField(upload_to=upload_path, keep_orphans=True)
upload = models.DateTimeField(auto_now_add=True)
您可以这样使用它:photo.photo.name\u base
。请确保传递到字段keep_or孤=True
,否则它将删除旧文件。在本例中,使用os.path.basename(self.file.name)而不是file.name可能会对您有所帮助
class FileModel(models.Model):
file = models.FileField(upload_to="images/")
def __unicode__(self):
return str(os.path.basename(self.file.name))
@property
def filename(self):
return str(os.path.basename(self.file.name))
在模板文件中使用file.url
class Photo(models.Model):
def upload_path(self, name):
return '{0}/{1}'.format(
self.album.title,
name.lower().replace(' ', '_').encode('trans')
)
photo = models.ImageField(upload_to=upload_path)
因此,如果将upload_to定义为类方法,则可以通过相关对象的字段“title”进行操作,例如将其作为子目录包含到映像路径中。尝试os.path.join([…])
@Cloudream不确定这会有什么帮助。如果upload\u to=some\u func
,请详细说明。Django将尝试将文件名保存为我的媒体根目录的相对路径。我现在看到的是,Django正在将文件名保存为我上传文件的相对路径,从媒体根开始。例如,文件名将命名为album1/photo.jpg
。文件将位于媒体/root/album1/
中。文件位置已找到,但文件名将为album1/photo.jpg
您的MEDIA\u ROOT
设置为?MEDIA\u ROOT=os.path.join(BASE\u DIR,“../MEDIA\u ROOT/Boothie/pics”)MEDIA\u URL='/MEDIA/'通常,除了简单的代码外,还应该包含一些解释代码如何回答问题或解决问题的文本。我理解你的意思,但我想知道如何防止文件名更改为string\u passed\u upload\u to/filename.ext
。只是不要通过upload\u to
关键字,但它将直接保存在MEDIA\u ROOT
目录中。我想按相册名称对我传递的照片进行排序。这就是为什么我在专辑中加入了album.title
I