【问题标题】:Accessing ForeignKey Properties访问外键属性
【发布时间】:2011-08-02 21:40:38
【问题描述】:

我有两个模型。基本上,我是从这个讨论中扩展而来的:Multiple images per Model 我想获取 Design 模型的 machine_name 的值,并将其用于为 DesignImage 模型中的 ImageField upload_to 创建路径。大意是:image = models.ImageField(upload_to='designs/' + design.get_machine_name + '/images')

这会产生以下错误:AttributeError: 'ForeignKey' object has no attribute 'get_machine_name'

我希望下面的代码是清晰的。

from django.db import models
from django.db.models.fields.related import ManyToManyField
from django.template.defaultfilters import slugify

class Design(models.Model):
    name = models.CharField(max_length=30, help_text='Name of the design.')
    machine_name = models.SlugField(editable=False)

    def save(self, *args, **kwargs):
        self.machine_name = slugify(self.name)
        super(Design, self).save(*args, **kwargs)

    def get_machine_name(self):
        return self.machine_name

    def __unicode__(self):
        return self.name

class DesignImage(models.Model):

    def get_upload_dir(self):
        return 'designs/' + self.design.machine_name + '/images'

    design = models.ForeignKey(Design, related_name='images')
    caption = models.CharField(max_length=100)
    image = models.ImageField(upload_to='designs/' + design.get_machine_name + '/images')

    def __unicode__(self):
        return self.caption

我已经包含了以下代码,以防它可能有用:

from designs.models import *
from django.contrib import admin

class DesignImageInline(admin.TabularInline):
    model = DesignImage
    extra = 3 # number of extra inline form fields to display

class DesignAdmin(admin.ModelAdmin): 
    inlines = [ DesignImageInline, ]

admin.site.register(Design, DesignAdmin)
admin.site.register(DesignImage)

【问题讨论】:

  • 您应该更改标题以反映“在 ImageField 上传中使用外键属性”或类似的实际问题

标签: django django-models django-admin


【解决方案1】:

如果ImageField 上传到的位置取决于实例(就像这里所做的那样),upload_to 参数可以是可调用的而不是字符串,其中将传递当前实例和文件名。你需要这样的东西:

import os 

def upload_to(instance, filename):
    return os.path.join('designs', instance.design.machine_name, 'images', filename)

...
    image = models.ImageField(upload_to=upload_to)

【讨论】:

    【解决方案2】:

    问题出在这一行:

    image = models.ImageField(upload_to='designs/' + design.get_machine_name + '/images')

    字段设计不是在“编译时”定义的,它是模型中的另一个字段。

    您需要在运行时将其应用到您要编辑的每个表单中。

    【讨论】:

    • 啊,谢谢你的洞察力。 isbadawi 的解决方案很好地应用了这一点。
    • 我一定会的。我只是没有(还)所需的 15 个声望点,但我会记住这些帖子。
    猜你喜欢
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2016-03-13
    • 2014-08-12
    • 1970-01-01
    • 2023-03-23
    • 2015-06-03
    相关资源
    最近更新 更多