Django "Save As New" and save the "Image" fields

I have a Django model with several ImageFields.

In the ModelAdmin class, I set save_as save_as = True , which means that on the admin page there is a Save As New button that allows you to duplicate an existing item and save it as new.

However, when this button is used, ImageField are not duplicated and remain empty for the new element.

Looking at the POST request, I see that these fields are empty in the message data.

I thought about overriding the method of saving the model class and copying images from the old object myself. But, as far as I could understand, I can’t say that the object is saved “like new”. I also do not have the identifier of the old element, so I cannot get old images from it.

Can these image fields be duplicated?

Edit: Added sample code on request.

Created a minimalistic application with only one model. A verified issue is still happening.

Example models.py:

 from django.db import models class Person(models.Model): face_image = models.ImageField(upload_to='images', null=False, blank=True) 

Example admin.py:

 from django.contrib import admin from testapp.models import Person class PersonAdmin(admin.ModelAdmin): save_as = True admin.site.register(Person, PersonAdmin) 
+6
django
Sep 02 '13 at 16:21
source share
3 answers

I managed to find a workaround:

I redefined the original admin form (see here) to get it, also including the old model identifier in "save as new", POST request. I did this by creating a special admin for this model and adding hidden input inside it:

 <input type="hidden" name="my_objectid" value="{{ object_id }}"> 

after that I made loading the ModelAdmin class specific html. Then I override the save_model method of the AdminModel class so that it also copies the images.

So the new admin.py should look like this:

 from django.contrib import admin from testapp.models import Person from django.db.models.fields.files import ImageFieldFile #added to be used later class PersonAdmin(admin.ModelAdmin): save_as=True change_form_template = 'admin/person_change_form.html'; def save_model(self, request, obj, form, change): if '_saveasnew' in request.POST: #Django always sends this when "Save as new is clicked" origObjId = request.POST['my_objectid']; #Get the ID that is new posted after overriding the form. originalPerson = Person.objects.get(id=origObjId); #Use the Id to get the old object for prop, value in vars(originalPerson).iteritems(): #iterate through all it properties if isinstance(getattr(originalPerson,prop), ImageFieldFile): #if the property is an Image (don't forget to import ImageFieldFile!) setattr(obj,prop,getattr(originalPerson,prop)) #Copy it! obj.save() admin.site.register(Person, PersonAdmin) 
+6
Sep 03 '13 at 15:44
source share

Configure this answer, here is a more general way to achieve the same result:

 from django.core.urlresolvers import resolve from django.db.models.fields.files import FieldFile class PersonAdmin(admin.ModelAdmin): save_as = True def save_model(self, request, obj, form, change): # Django always sends this when "Save as new is clicked" if '_saveasnew' in request.POST: # Get the ID from the admin URL original_pk = resolve(request.path).args[0] # Get the original object original_obj = obj._meta.concrete_model.objects.get(id=original_pk) # Iterate through all it properties for prop, value in vars(original_obj).iteritems(): # if the property is an Image (don't forget to import ImageFieldFile!) if isinstance(getattr(original_obj, prop), FieldFile): setattr(obj,prop,getattr(original_obj, prop)) # Copy it! obj.save() 

This should work with any model and any type of file. It also does not require editing a form or template. This is a workaround that should not be necessary after the download request has been merged: https://github.com/django/django/pull/2246 .

+6
Jun 11 '14 at 11:41
source share

Here is a ticket that describes the same problem: "Administrator opening lines with file / image field cannot be saved"

Since February 9, 2014 there is a pull request that corrects this error. Most likely, it will be combined.

+2
Feb 09 '14 at 20:57
source share



All Articles