Question

I'm creating some instances of the Item model shown below from a csv file. In the csv file only the name and the filename of the Item is specified. The image field is set by looking if the image exists, and if it does, set the image file to image:

I do:

item = Item()
item.name = csv_fields[0]
item.filename = csv_fields[1]
item.save()

...

f = open(settings.MEDIA_ROOT+"images/"+item.filename, 'r')
item.image = File(f)
item.save()

Doing so, the image is duplicated in settings.MEDIA_ROOT+"images/" as <original filename>_1. How can avoid that? i.e. how can I just set an existing file to an imagefield, without copying it?

class Item(models.Model):   

    name = models.CharField(max_length=50)
    filename = models.CharField(max_length=100,)
    image = models.ImageField(upload_to='images', blank=True, null=True)
Was it helpful?

Solution

This is all you need

item = Item()
item.name = csv_fields[0]
item.filename = csv_fields[1]
item.image = csv_fields[1]
item.save()

the image field takes a filename and the field definition's upload_to, and converts that to an image resource. if you pass in an image resource, it thinks its making a new one.

SO this:

f = open(settings.MEDIA_ROOT+"images/"+item.filename, 'r')
item.image = File(f)

isn't necessary at all

the only diff between a charfield and a image field is that a imagefield takes the filename and casts it to a PIL Image resource for further manipulation. its just a wrapper.

OTHER TIPS

Francis Yaconiello answer is correct, but I have one clarifying detail.

item.image = csv_fields[1]

Note that this should be a path relative to the media root or other storage root.

For example, say settings.MEDIA_ROOT = '/home/myuser/media' and the ImageField(upload_to='images').

So if you manually save an image at `/home/myuser/media/images/purty.jpg', then csv_fields[1] should be:

item.image = '/images/purty.jpg'

Other wise, item.image.name, item.image.path, and item.image.url will be messed up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top