2013-01-20 18 views
3

我有一个缩略图宽度因父对象(ForeignKey)而异的模型。我需要能够将这些信息提供给imagekit处理器。这是我的:django imagekit处理器:使用存储在数据库中的尺寸

class Wall(models.Model): 
    #... 
    width = models.SmallIntegerField(null=True, blank=True) 
    #... 


class Poster(models.Model): 
    wall = models.ForeignKey(Wall, related_name='posters') 
    #... 
    original_image = models.ImageField(upload_to=upload_image_to) 

    def __init__(self, *args, **kwargs): 
     self.thumbnail = ImageSpecField([ 
       Adjust(contrast=1.2, sharpness=1.1), 
       SmartResize(height=163, width=self.wall.width) 
      ], 
      image_field='original_image', format='PNG' 
     ) 

     super(Poster, self).__init__(*args, **kwargs) 
    #... 

但是,如果我这样做,没有任何反应,甚至没有生成缩略图网址。

及以下将导致此此异常:
AttributeError的:“ForeignKey的”对象有没有属性“宽度”

class Poster(models.Model): 
    wall = models.ForeignKey(Wall, related_name='posters') 
    #... 
    original_image = models.ImageField(upload_to=upload_image_to) 

    thumbnail = ImageSpecField([ 
      Adjust(contrast=1.2, sharpness=1.1), 
      SmartResize(height=163, width=wall.width) 
     ], 
     image_field='original_image', format='PNG' 
    ) 
    #... 
+0

认真吗?没有人想要赏金? – demux

回答

4

您不能引用模型定义实例值。这是Django变得有点棘手的地方;模型是实例化时实例的外观的声明,这就是为什么相互依赖的字段必须按名称引用其他字段,例如image_field='original_image'规范。

从imagekit的源代码看,您可以看到processors可以采用静态处理器的列表来应用,或者它需要一个可调用的函数,它应该返回要在生成时应用的处理器列表。由于您希望基于宽度在运行时更改生成时间,因此您可以将其用于您的优势。

调用processors可调用,出现thumbnail字段的实例将允许您查看宽度。

def thumbnail_processors(instance, file): 
    # Dynamic width lookup. 
    width = instance.wall.width 
    return [ 
     Adjust(contrast=1.2, sharpness=1.1), 
     SmartResize(width=width, height=163), 
     ] 


class Poster(models.Model): 
    wall = models.ForeignKey(Wall, related_name='posters') 
    #... 
    original_image = models.ImageField(upload_to=upload_image_to) 

    thumbnail = ImageSpecField(
     processors=thumbnail_processors, 
     image_field='original_image', format='PNG' 
    ) 
    #... 

现在,当你访问现场,thumbnail_processors将被称为在运行时,而不是在模型声明,以获得处理器的列表。 width从您的外键获得,并执行适当的调整大小。

可能有一些需要调查的问题。当您访问thumbnail时,将根据您的宽度生成图像文件。如果稍后更改宽度并再次请求缩略图,我不确定存储和缓存后端的行为方式。很可能您需要一个自定义文件名称生成器,它可以对缩略图的宽度进行编码,以便当宽度发生变化时,将生成一个新的缩略图,其名称不同。

+0

我已经试过这个,但是诀窍是什么文件参数。谢谢,这节省了我许多小时的时间,将我的头撞在墙上。 – demux