在我的模型中我有:

class Alias(MyBaseModel):
remote_image = models.URLField(
    max_length=500, null=True,
    help_text='''
        A URL that is downloaded and cached for the image.
        Only used when the alias is made
    '''
)
    image = models.ImageField(
        upload_to='alias', default='alias-default.png',
        help_text="An image representing the alias"
    )

    
    def save(self, *args, **kw):
        if (not self.image or self.image.name == 'alias-default.png') and self.remote_image :
            try :
                data = utils.fetch(self.remote_image)
                image = StringIO.StringIO(data)
                image = Image.open(image)
                buf = StringIO.StringIO()
                image.save(buf, format='PNG')
                self.image.save(
                    hashlib.md5(self.string_id).hexdigest() + ".png", ContentFile(buf.getvalue())
                )
            except IOError :
                pass

这在remote_image第一次改变的时候工作得很好。

当有人修改了别名上的remote_image时,我如何获取一个新的图像?其次,是否有更好的方法来缓存远程映像?


当前回答

虽然这实际上并没有回答你的问题,但我会以不同的方式来讨论这个问题。

成功保存本地副本后,只需清除remote_image字段。然后在保存方法中,只要remote_image不为空,就可以随时更新图像。

如果您想保留对url的引用,您可以使用一个不可编辑的布尔字段来处理缓存标志,而不是使用remote_image字段本身。

其他回答

自从Django 1.8发布以来,你可以使用from_db类方法来缓存remote_image的旧值。然后在保存方法中,您可以比较字段的旧值和新值,以检查该值是否已更改。

@classmethod
def from_db(cls, db, field_names, values):
    new = super(Alias, cls).from_db(db, field_names, values)
    # cache value went from the base
    new._loaded_remote_image = values[field_names.index('remote_image')]
    return new

def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
    if (self._state.adding and self.remote_image) or \
        (not self._state.adding and self._loaded_remote_image != self.remote_image):
        # If it is first save and there is no cached remote_image but there is new one, 
        # or the value of remote_image has changed - do your stuff!

虽然这实际上并没有回答你的问题,但我会以不同的方式来讨论这个问题。

成功保存本地副本后,只需清除remote_image字段。然后在保存方法中,只要remote_image不为空,就可以随时更新图像。

如果您想保留对url的引用,您可以使用一个不可编辑的布尔字段来处理缓存标志,而不是使用remote_image字段本身。

作为SmileyChris回答的扩展,您可以为last_updated的模型添加一个datetime字段,并在检查更改之前为您将让它达到的最大年龄设置某种限制

我有点晚了,但我也找到了这个解决方案: Django脏域

我找到了这个包django-lifecycle。 它使用django信号来定义@hook装饰器,非常健壮可靠。我用过它,它是一种幸福。