简体   繁体   中英

How to “link” already uploaded images to ImageField in Django?

I have models like:

class Symbol(models.Model): 
    slug = models.SlugField(unique=True) #uniqe
    name = models.CharField(max_length=255, unique=True)
    imgslug = models.CharField(unique=False, max_length=255, blank=True) #uniqe

    def __str__(self):
        return self.name

class Platform(models.Model):
    name = models.CharField(max_length=50, unique=True)

    def __str__(self):
        return self.name

class PlatformImages(models.Model):
    symbol_id  = models.ForeignKey('Symbol', on_delete=models.CASCADE,) 
    platform_id = models.ForeignKey('Platform', on_delete=models.PROTECT,)

    class Meta:
        indexes = [
            models.Index(fields=['symbol_id', 'symbol_id']),
        ]
        constraints = [
            models.UniqueConstraint(fields=['symbol_id', 'platform_id'], name='unique_symbol_img_per_platform')
        ]

    def __str__(self): 
        return str(self.platform_id)

    def get_platform_name(self):
        return self.platform_id

I have folders per platform in media folder like: media/apple/, media/google/, media/twitter/,etc.

Inside each folder there are ~1000-3000 images, named as "imgslug" for almost each Symbol. I had uploaded them in a batch.

And I use it In template to show all available images for symbol per platform:

{% for platform in platforms %}
    <img src="{{ MEDIA_PREFIX }}{{platform}}/{{symbol.imgslug}}" >
    <h2 class="">{{platform|title}}</h2>
{% endfor %}

The problem is that now I need to edit/upload new images via Admin tool. I added this code to admin.py to edit mapping of image to Platform:

class PlatformInline(admin.TabularInline):
    model = PlatformImages

class SymbolAdmin(admin.ModelAdmin):
    inlines = [
        PlatformInline,
    ]

Now I think to add ImageField to PlatformImages Model, but I need:

  • to save each image per unique platform for symbol in corresponding folder
  • to add there already uploaded files

And I don't know how to do it to achieve something like this: 在此处输入图像描述

After digging the web, I came to following solution:

  1. to save each image per unique platform for symbol in corresponding folder added to models.py:

     class Platform(models.Model): name = models.CharField(max_length=50, unique=True) folder = models.SlugField(unique=True, null=True, blank=True) def platform_directory_path(instance, filename): return '{0}/{1}'.format(instance.platform_id.folder, filename) class PlatformImages(models.Model): symbol_id = models.ForeignKey('Symbol', on_delete=models.CASCADE,) platform_id = models.ForeignKey('Platform', on_delete=models.PROTECT,) image = models.ImageField(upload_to=platform_directory_path, null=True, blank=True)

2) to link already uploaded images to ImageField, open shell

python3 manage.py shell

and execute script:

from django.db import models
images = PlatformImages.objects.all()
for image in images:
    platform = image.platform_id.name
    symbol = image.symbol_id.imgslug
    imagePath = str(platform +'/'+symbol)
    print (str(image.id) + " : " + imagePath)
    image.image = imagePath
    image.save()

What helped me to find that solution:

Django docs - upload_to may also be a callable, such as a function

How to link already existing image to an ImageField

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM