0

我有 3 个模型。

class Picture(models.Model)
  name = models.CharField(max_length=255)
  image_field = models.ImageField(upload_to="foo/")
  slug = models.SlugField()
  [...]


class Size(models.Model):
  name = models.CharField(max_length=255)
  width = models.IntegerField()
  height = models.IntegerField()
  crop = models.BooleanField(default=True)
  upscale = models.BooleanField(default=False)

  def __unicode__(self):
    return self.name

class Cache(models.Model):
  size = models.ForeignKey('Size')
  picture = models.ForeignKey('Picture')
  image_field = models.ImageField(upload_to="picture/resize/")

我想按如下方式使用它们:首先生成图片对象。然后创建 Size 对象。对于每个大小和图片,都应该在需要时生成一个缓存对象。

我的问题是我不知道把代码放在哪里。它应该类似于(伪代码):

def get_cached_picture(Picture,Size):
  try:
    cacheObj = Cache.objects.get(picture=Picture, size=Size):
    [.. use cacheObj  ..]
  except Cache.DoesNotExist:
    [.. resize Picture according to Size, insert into cache, use it ..]

那么我在哪里可以插入此代码?我知道我可以在视图中做到这一点,但有没有办法将它嵌入到模型中?缓存永远不应该在管理员中填充,而是应该在需要缓存和图片之间的某种组合时生成。

这可能很容易做到,但我缺少谷歌的正确关键字。

4

1 回答 1

2

假设:

  1. 您希望能够动态加载特定大小的图像“表示”。
  2. 尺寸模型将存储表示可以具有的一组预定义尺寸。

我将把你的缓存模型称为表示,因为我认为在这里的上下文中更有意义。

这个过程的切入点显然是一个视图。收到一个请求,您确定需要搜索“Image1.jpg”@800x600。最简单的方法是将您的查询直接放入视图中。但是为了可重用性,最好执行以下任何操作:

  • 一个实用函数,然后从视图中调用它来检索一个表示对象
  • Representation 模型的类方法,因为您已经将 Picture 和 Size 作为外键引用。
  • 在 Representation 模型上使用自定义管理器来执行与上述类似的操作

如果其他人有自己的视图并且需要直接检索 Rep 实例,则任何这些都将使其可作为应用程序重用。

虽然您的伪代码指的是这个过程在图片模式下,但我认为它可能应该在表示模型上,因为它包含两个外键,您可以轻松查看是否有适当的代表。如果没有,请创建它。

视图应该只需要调用一些简单的东西,而不是拥有所有的逻辑:

# as classmethod
rep = Representation.get_cached_picture(picture, size)
# or with a manager
rep = Representation.objects.get_cached_picture(picture, size)
于 2012-04-22T21:40:16.347 回答