问题
I want to change my ImageField's attribute, however I'm constantly getting the Can't set attribute error.
My model is
class Society(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
summary = models.TextField(blank=True,null=True)
members = models.ManyToManyField(User,null=True,blank=True)
gallery = models.ForeignKey(Gallery,null=True,blank=True)
avatar = models.ImageField(upload_to=get_society_path)
def save(self,*args,**kwargs):
super(Society, self).save(*args,**kwargs)
fix_avatar_path(self)
def clean(self):
if self.id:
self.avatar.path = get_society_path(self,self.avatar.path)
save_thumb(self.avatar.path)
And my helper functions are :
def get_society_path(instance,filename):
seperator_val = instance.id
if seperator_val is None:
seperator_val = get_time()
return '%s/society_%s/%s' % (settings.UPLOAD_ROOT,seperator_val,time_to_name(filename))
def fix_avatar_path(instance):
org_society_path = get_society_path(instance,instance.avatar.name)
make_upload_dir(org_society_path)
move(instance.avatar.path,org_society_path)
os.rmdir(os.path.dirname(instance.avatar.path))
instance.clean()
The problem is :
I want to save my society directories as society_society_id. But normally, I can't assign any id before the model is saved. So i'm creating a tmp file whose name is a time value.Then to reach societies folder, I want to rename this file. So, my fix_avatar simply moves the tmp file's content to society_(society_id) folder after the society is saved. So far so good everything works well. However, my society's ImageField still holds the previously created folder. In order to change it's value, I found that i can use clean method.(from this SO question) But still i'm getting the same result, the path doesn't change, and gives the "can't set attribute" response.
Any idea ??
回答1:
Not sure, if this was ever changed in Django since this question was asked. A ticket about this not being possible still exists: https://code.djangoproject.com/ticket/15590
However, you actually can change the path by doing it like this:
self.avatar = 'uploads/example/path/'
What also does the job:
self.avatar.name = 'uploads/example/path/'
It has worked for us in several occasions.
回答2:
The problem is here:
self.avatar.path = get_society_path(self,self.avatar.path)
You cannot change the value of the path attribute in FileField/ImageField instances, it's readonly. There is a proposal to change this in Django 1.4
来源:https://stackoverflow.com/questions/5189114/cant-set-imagefield-url-attribute