0

Recently I started experimenting with Python and Django. I like it, learned already a lot, but still a long way to go...

I made a model containing 5 image fields. Next to the model I also made a form to enter data and save it. So far so good. Now I want to write another form to 'edit' the uploaded images, meaning:

  1. upload new images
  2. delete the 'old' images from the database

I wrote the code below that does the job for 1 image:

if form.is_valid():
            form_image = form.cleaned_data['image_1']
            try:
                details = Model.objects.get(pk=pk)
                if details.image_1 != form_image:
                    details.image_1.delete(save=False)
            except: pass # when new photo then we do nothing, normal case
            form.save()

But I am struggling with following problems:

  1. How can this code be rewritten to update 5 image fields? Because in worst case one can edit all 5 image fields. I tried with a 'for loop' but never succeed. For example:

    image_list = [image_1, image_2, image_3, image_4, image_5]
    if form.is_valid():
        for image in image_list:
            form_image = form.cleaned_data[image]
            try:
                details = Model.objects.get(pk=pk)
                if details.image != form_image:
                    details.image.delete(save=False)
            except: pass # when new photo then we do nothing, normal case
            form.save()
    
  2. Are there more intelligent ways to write this piece of logic. A problem that I have with this code is that it checks on the name of the image. And probably this goes wrong when I have multiple images with the same name...

Hopefully someone can give some feedback and point me again in the right direction.

Many thanks!

Kind Regards

Köver
  • 371
  • 4
  • 12
  • Hi again, the naming issue is solved: I can make the image name unique, using this renaming technique: [Django FileField with upload_to determined at runtime](http://stackoverflow.com/questions/1190697/django-filefield-with-upload-to-determined-at-runtime). But still the first point remains: how to loop over different images? And is this piece of code 'intelligent' meaning, is this the best way to handle the image upload? Thanks! – Köver Jun 19 '12 at 16:13

1 Answers1

1

You need to use strings:

image_list = ['image_1', 'image_2', 'image_3', 'image_4', 'image_5']

# or doing that dynamically as well:
image_list = ['image_%d' % i for i in xrange(1,6)]

Also, from your example, I am not sure where you are getting a unique pk value each time. But assume each loop should produce a different details object to compare to that specific image.

One thing to consider is that you should almost never do a blanket try, except: pass. It can easily mask errors that you didn't consider:

try:
    details = Model.objects.get(pk=pk)
    ...
# django models have a special exception type
# when they don't exist.
except Model.DoesNotExist: 
    pass 

In order to dynamically use those string names as variable lookups, you just need to use getattr

for image_name in image_list:
    ...
    # equiv to: details.image_1, details.image_2, ...
    if getattr(details, image_name, None) != form_image:
    ...
jdi
  • 90,542
  • 19
  • 167
  • 203
  • Thanks for the feedback jdi. The problem with the strings is that I can't use it for the `details.image`. In the code I actually want to loop with the same variable on two places: `form.cleaned_data['variable']` and `details.variable`. Is this possible somehow? Thanks! – Köver Jun 20 '12 at 19:15