2012-07-23 109 views
0

我有一个简单的结构,产品模型,AppMedia模型和ProductMedia连接表。Django Admin以嵌入形式显示外键的imagefield的缩略图

产品(有很多)ProductMedia

ProductMedia(有)AppMedia

我真的想是看到AppMedia媒体领域的缩略图在产品内嵌形式。

例如编辑Django admin中的产品,显示一个StackedInline表单。这包含(目前)下拉(选择)所有AppMedia。

我需要的是缩略图。

任何帮助表示赞赏。

我确定这不难,但我很挣扎。为AppMedia表单(这是媒体ImageField所在的位置)放置缩略图非常简单,但不适用于将AppMedia用作ForeignKey的ProductMedia表单。

基本模型......

class Product(models.Model): 
    name    = models.CharField(max_length=100) 

class AppMedia(models.Model): 
    media   = models.ImageField(upload_to=appmedia_upload_to) #appmedia_upload_to defined elsewhere) 

class ProductMedia(models.Model): 
    title   = models.CharField(max_length=150) 
    media   = models.ForeignKey(AppMedia) 
    media_order  = models.IntegerField(default=0) 
    product   = models.ForeignKey(Product) 

的AppMedia以这种方式共享停止同一文件的多个上传并存储额外的元数据(这里不显示)与图像。

回答

-1

你应该看看related_name参数外键,这将允许您访问ProductMedia相反,也就是说,如果你改变了ProductMedia模式:

class ProductMedia(models.Model): 
    title   = models.CharField(max_length=150) 
    media   = models.ForeignKey(AppMedia) 
    media_order  = models.IntegerField(default=0) 
    product   = models.ForeignKey(Product, related_name='media') 

你可以访问产品的媒体对象模型,它可以让你把它放在你的管理员联机表格中。即你必须(对一个更简单的解释,我已经把ProductMedia中的ImageField):

class Product(models.Model): 
    name    = models.CharField(max_length=100) 

    def admin_image(self): 
     return '<img src="%s"/>' % (self.media.all()[0].image.url) 
    admin_image.allow_tags = True 

class ProductMedia(models.Model): 
    title   = models.CharField(max_length=150) 
    image   = models.ImageField(upload_to=appmedia_upload_to) #appmedia_upload_to defined elsewhere) 
    media_order  = models.IntegerField(default=0) 
    product   = models.ForeignKey(Product, related_name='media') 

然后在您的admin.py地说:

class ProductAdmin(admin.ModelAdmin): 
    list_display = ('name', 'admin_image') 

admin.site.register(models.Product, ProductAdmin) 

https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.related_name

希望我理解你的问题正确并且有所帮助。此外代码没有测试,但我很确定它应该工作。

+0

这句话虽然从理论上回答这个问题,我们希望你能包括在你的答案链接的文章的主要部分,并提供[链接以供参考](http://meta.stackexchange.com/q/8259)。如果做不到这一点,答案就会受到链接腐败的威胁。 – Kev 2012-09-29 14:49:11

+0

好的,现在就可以做到 – Parham 2012-09-29 17:23:56

+0

这个解决方案使得该模型与管理应用程序紧密结合。 – Dor 2014-05-14 05:53:58

0

我有同样的问题。我希望我的尝试至少一个将是你的情况下可用:

我首先要解决这个问题(没有覆盖ForeignKeyRawIdWidget)的尝试是:

  • 设置form财产直列管理员那里缩略图应显示的
  • 添加一个字段与小部件给出窗体类,这将显示缩略图

但是我放弃了这个方案,因为我觉得我有注资约thumbn数据在表单的构造函数中进入给定的字段,我不认为这是一个很好的解决方案。

我的下一个解决方案是在某些领域使用MultiWidget。在这种情况下,我不需要添加另一个字段来形成,而且我将获得在小部件中显示缩略图所需的数据,而无需在构造函数中注入它们。

class ThumbnailMultiWidget(MultiWidget): 

    def decompress(self, value): 
     #has to be overriden 
     return [None,None] 


class ThumbnailWidget(Widget): 

    def render(self, name, value, attrs=None): 
     #not quite sure what is in `value`, I've not been so far 
     return '<img src="%s"/>' % value.url 


class PhotoInlineForm(forms.ModelForm): 


    def __init__(self, *args, **kwargs): 
     super(PhotoInlineForm, self).__init__(*args, **kwargs) 


     wdgts = [self.fields['media'].widget, ThumbnailWidget()] 
     self.fields['media'].widget = ThumbnailMultiWidget(widgets=wdgts) 


    class Meta: 
     model = RecipePhoto 

但我放弃了这种解决方案为好,因为我发现,实际上有一个实例的表示在ForeignKeyRawIdWidget(这是小部件我使用)与我需要显示缩略图的所有数据。这是我最后的解决办法:

所以,因为我的内联项目具有raw_id_field为选择一个内嵌的记录,我可以简单地重写方法label_for_valueForeignKeyRawIdWidget,它是用来表示现有的在线纪录。通常是__unicode__(我认为)。我继承ForeignKeyRawIdWidget和重写这个方法来显示图像缩略图:

class PhotoForeignKeyRawIdWidget(ForeignKeyRawIdWidget): 

    def label_for_value(self, value): 
     key = self.rel.get_related_field().name 
     try: 
      obj = self.rel.to._default_manager.using(self.db).get(**{key: value}) 
     except (ValueError, self.rel.to.DoesNotExist): 
      return '' 
     else: 
      """ 
      there's utilized sorl.thumbnail, but you can return st like this: 
      <img src='%s' /> % obj.media.url 
      """ 
      return Template("""{% load thumbnail %} 
      {% thumbnail image.image "120x120" crop="center" as one %} 
       <img src="{{ one.url }}" /> 
      {% endthumbnail %}""").render(Context({ 
       'image': obj 
      })) 


class AppMediaInlineAdmin(admin.TabularInline): 
    model = AppMedia 
    extra = 1 

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs): 
     if db_field.name == 'media': 
      db = kwargs.get('using') 
      kwargs['widget'] = PhotoForeignKeyRawIdWidget(db_field.rel, self.admin_site, using=db) 
     return super(AppMediaInlineAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)