开发者

Accessing ForeignKey Properties

I have two models. Basically, I am extending from this discussion: Multiple images per Model I would like to get the value of the machine_name of the Design model and use it in creating a path for the ImageField upload_to in the DesignImage model. Something to the effect of: image = models.ImageField(upload_to='designs/' + design.get_machine_name + '/images')

This is producing the following error: AttributeError: 'ForeignKey' object has no attribute 'get_machine_name'.

I hope the code below is clear.

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 + '/ima开发者_如何学运维ges'

    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

I have included the following code in case it may be useful:

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)


In case the location an ImageField is uploaded to depends on the instance (as it does here), the upload_to argument can be a callable instead of a string, in which it will be passed the current instance and the filename. You need something like this:

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)


The problem is in this line:

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

The field design is not defined at "compile time", it's another field in the model.

You will need to apply that at runtime in what every form you are using to edit.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜