Django - 获取带外键的对象

2 投票
2 回答
3938 浏览
提问于 2025-04-18 10:05

版本信息:

Python 3.4

Django 1.7

我创建了一个图库应用,里面有不同的画廊和各自的图片。

我的模型:

from django.db import models


class Gallery(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('publish date')

    def __str__(self):
        return self.title


class Image(models.Model):
    title = models.CharField(max_length=200)
    gallery = models.ForeignKey(Gallery)
    pub_date = models.DateTimeField('publish date')
    file = models.ImageField(upload_to='img/gallery/'+str(Gallery.objects.get(pk=str(gallery)).id)+'/')

    def __str__(self):
        return self.title

你可以看到我的Gallery(画廊)和Image(图片)模型。在后台创建Image时,它应该动态地在"img/gallery/gallery_id"中创建一个文件夹。

我遇到的问题是,Image.gallery是一个外键(ForeignKey),我不能把它转换成整数或字符串来使用。有没有什么方法可以从我的Image对象中获取与之关联的Gallery对象的ID呢?

我的解决方案:

Gallery.objects.get(pk=str(gallery)).id

并没有奏效。

顺便问一下,我以为外键总是像ID那样是个整数,对吧?

2 个回答

2

上传的路径可以是一个回调函数:

https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.FileField.upload_to

所以:

def gallery_folder(instance, filename):
    return '/'.join(['img/gallery', instance.gallery.id, filename])

class Image(models.Model):
    title = models.CharField(max_length=200)
    gallery = models.ForeignKey(Gallery, related_name='images')
    pub_date = models.DateTimeField('publish date')
    file = models.ImageField(upload_to=gallery_folder)

    def __str__(self):
        return self.title

另外,添加 related_name 这个选项可以让反向查询变得更简单。如果你想的话,也可以使用 instance.gallery.title

2

Django的工作方式是,它会自动添加一个方便的方法,让你可以直接获取外键所代表的模型实例。这就是你的 gallery 字段。还有一个字段,名字和它一样,但后面加了 _id,这个字段存的是实际的外键值。

正如petkostas所说,你可以传递一个函数,这个函数需要接受 instancefilename 这两个参数。你应该使用 gallery_id,而不是 gallery.id,这样可以避免不必要的数据库查询。

def gallery_folder(instance, filename):
    return '/'.join(['img/gallery', instance.gallery_id, filename])

class Image(models.Model):
    ...
    file = models.ImageField(upload_to=gallery_folder)

撰写回答