Django - 通过ForeignKey属性向模型传递参数

2 投票
2 回答
1174 浏览
提问于 2025-04-16 09:56

我有一个这样的类:

class Image (models.Model):
    ...
    sizes = ((90,90), (300,250))

    def resize_image(self):
        for size in sizes:
            ...

还有另一个这样的类:

class SomeClassWithAnImage (models.Model):
    ...
    an_image = models.ForeignKey(Image)

我想对这个类做的事情是这样的:

class SomeClassWithAnImage (models.Model):
    ...
    an_image = models.ForeignKey(Image, sizes=((90,90), (150, 120)))

我希望能够指定一些尺寸,让Image类根据这些尺寸来调整自己,而不是在类里面写死这些尺寸。我知道如果直接调用resize_image方法,我可以把这些尺寸作为参数传进去,但我的想法是,当对象保存到数据库时,resize_image方法会自动被调用。

如果我尝试通过外键声明来传递参数,就会立刻出现错误。有没有什么简单或者更好的方法可以做到这一点,而不需要深入研究django的内部?

2 个回答

0

在Django中,一个对象的所有属性都存储在数据库里,所以你需要把尺寸设置为模型中的一个字段。你不能随便设置一些属性,然后指望它们能一直保存下去。

因为没有直接用来存储元组列表的字段,你要么用文本字段来凑合一下,要么自己写一个ListOfTuplesField,或者更好的是,写一个继承自ListOfTuplesField的ImageSizesField。你需要写代码把它转换成数据库能识别的格式(把它转成文本可能是最简单的方法),还要能把它解析回来,或者可能有某种JSONField类型可以用。

所以现在你的SomeClassWithAnImage模型有一个外键指向Image,还有一个ImageSizesField。当你保存这个模型时,你重写的save()方法会用ImageSizesField里的值调用Image的resize方法。

但是如果另一个SomeClassWithAnImage也指向同一个Image,那会发生什么呢?

0

你可能在做一件不太常见的事情;通常不太会尝试给外键(FK)加上参数。

解决你这个问题的常见方法是使用一个缩略图生成器(比如“sorl”),在发送之前立即生成缩略图,也就是说:在模板中,比如:

{% thumbnail myobj.image 500 500 %}

不过我个人是把一些功能加到我的类里,这样可以更方便地访问这些缩略图。比如:

def thumbnail(self):
     path = # work out the path to the thumbnail
     try:
         #access the path where I expect the thumbnail file to be
     except #failure:
         # generate the thumbnail using the dimensions specified by the class
     return #path to the thumbnail

撰写回答