我不确定如何将目录中的图像显示到页面上。我正在尝试创建一个图库应用。我正在尝试一点一点地做这件事。我的目标是为专辑创建缩略图(照片的第一张图片)。单击相册时,应显示所有图像。我认为这将通过AJAX请求完成。不太确定,因为我是Web开发的新手。我需要一些帮助来设置它。
图像结构:
/gallery
/static
/images
/album1
img1
/album2
img2
...etc
我不确定如何在我的views.py中获取这些图像并将其显示在html页面上。
这是我想出的models.py,但可能需要更多的工作:
class Album(models.Model):
title = models.CharField(max_length = 60)
def __unicode__(self):
return self.title
class Image(models.Model):
title = models.CharField(max_length = 60, blank = True, null = True)
tags = models.ManyToManyField(Tag, blank = True)
albums = models.ManyToManyField(Album, blank = True)
width = models.IntegerField(blank = True, null = True)
height = models.IntegerField(blank = True, null = True)
我觉得我可能会错过我的Image类中的一些内容,例如ImageField
或FileField
,但我手动将这些文件放在目录中,所以我不确定是否需要。< / p>
答案 0 :(得分:5)
在这个阶段,我们不可能完整地回答你的问题,但让我们看看。
答:目录和文件组织
目前尚不清楚您的目录结构如何与您的模型相似。
您的图片与相册有N:M的关系。到目前为止还可以。 令人困惑的是你的图像结构。
该结构看起来像是图像和专辑的1:1关系。 如果图像属于多个相册,是否会导致重复文件?
首先需要解决一件事:如何在硬盘上组织图像?
B:查找文件并从中创建网址
现在我们需要找到一种方法来查找图像文件的路径。我们假设,您的文件与django应用程序驻留在同一台机器上,因此我们可以使用本地路径。如果您的图片位于AWS之类的其他位置,则需要提供不同的机制来获取图片网址。
完成整理后,您可以为图像模型编写模型方法以检索图像路径。 一个简单的方法是你的标题是一个独特的字段,并且与你的图像文件名相同,它也必须是唯一的。我保证,这只适用于散列文件名或非常奇怪的文件名约定,当文件上传到您的图库时,您必须自己编写。当然还有其他选项可以确保您获得正确的文件,但让我们保持简单,只需记住一些事项。
C:一些示例代码
好的,让我们写一些代码。这只是一个人为的例子,想要解释基本思想。有关目录遍历的更多信息,请访问: Looking for File Traversal Functions in Python that are Like Java's
#models.py
import os
from os.path import join
class Image(models.Model):
def get_image_path(self):
for root, dirs, files in os.walk('<parents of gallery>/gallery/static/images/<album_if_required>'):
#debug information, just to get an idea how walk works.
#currently we are traversing over all files with any extension
print "Current directory", root
print "Sub directories", dirs
print "Files", files
for file in files:
if file.startswith(self.title):
#now we have found the desired file.
#value of file: "myimagetitle.jpg" <-- no path info
#value of root: "/home/yourhome/gallery/static/images/myalbum"
#we want to use this information to create a url based on our static path, so we need only the path sections past "static"
#we can achieve this like so (just one way)
mypath = os.sep.join(os.path.join(root, file).split(os.sep)[4:])
#yields: /images/myalbum/myimagetitle.jpg
return mypath
很好,现在我们有了一条路径,我们可以在模板中使用static作为基础。
#template.html
<!-- fancy html stuff goes here -->
<img src="{static myimage.get_image_path}">
<!-- more html -->
D:代码说明
我认为此代码的某些部分需要解释。
os.walk是一个生成器方法,它将遍历传递给它的路径。它将返回它所查看的当前节点(根)以及您可以在下面找到的子目录(dirs)和文件(文件)的路径。您可以从树中删除节点或节点模式,因此您可以对某些对象进行过滤。但现在这种情况会很遥远。
一旦找到了我们文件的候选者,我们需要构建一个可以在我们的应用程序中使用的路径。 HTML模板无法使用文件的物理位置,因此我们需要将其转换为URL。你必须知道你的网址方案是什么样的。我以为你依赖静态文件夹。
URL创建在这里:
os.sep.join(os.path.join(root, file).split(os.sep)[4:])
让我们看看它的部分内容:
os.path.join(root, file)
#join根路径和一个长字符串的文件名
.split(os.sep)[4:]
#get路径的子串。我们通过os依赖的目录分隔符char来分割路径。这将返回一个列表。我们只想要“静态”部分下的元素,在我的例子中,这导致了列表中的元素4
os.sep.join(...)
#last但并非最不重要的是我们必须再次构建一个字符串。所以我们将所有列表元素与目录分隔符连接起来,产生'/images/myalbum/myimagetitle.jpg'
正如您所看到的,这只是实现您想要的一种可能方式。如果您提供有关文件组织方式的更多信息,我相信我们可以找到更好的方法。请注意上面的代码还没有准备好生产!
答案 1 :(得分:1)
在Django中你应该使用 ImageField 并定义将生成&#34; upload_to&#34;的函数。图像的参数:
def images_upload_to(instance, filename):
return '/'.join(['images', instance.album.title])
class Image(models.Model):
title = models.CharField(max_length = 60, blank = True, null = True)
tags = models.ManyToManyField(Tag, blank = True)
albums = models.ForeignKey(Album, blank = True)
img = models.ImageField(upload_to=images_upload_to,null=True,blank=True)
您可以通过 {{image.img.height}} 和 {{image.img.width}}
在模板中访问的图片的维度在此解决方案中,您无法将ManyToManyField用于相册,因为您的目录结构与之相反。如果您希望使用ManyToManyField,则images_upload_to
功能无法根据一个相册生成目录路径。
首先,图库图片不应存储在static
目录中,而应保存在media
中。静态文件适用于js / css / images等,根据定义,它们是静态的&#39;静态文件。并且不会改变,但媒体文件是用户上传的内容。