Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a file location in a FileField?

I have a FileField in a model. For each instance of the model, I would like that the filename on the disk stays updated with the value of another field (let's call it label) of the model.

At the moment, I use a custom upload_to() function that generates the right filename when a new file is first uploaded. But if I change the value of label, the filename is not updated when saving the model.

In the save() function of the model I could (a) calculate the new filename from label (also checking that the new name would not correspond to another existing file on the disk), (b) rename the file on the disk and (c) set the new file location in the FileField. But is there no simpler way to do that?

like image 837
mimo Avatar asked Aug 26 '14 21:08

mimo


2 Answers

I think your approach with the save() method is the right and "simple" one except I would do it using the pre_save signal instead of overriding the save method (which is often a bad idea).

If this is a behavior you would like to repeat on other models, using a method connected to the pre_save signal also allows you to simply re-use the method.

For more information on pre_save: https://docs.djangoproject.com/en/1.8/ref/signals/#pre-save

like image 137
Emma Avatar answered Oct 05 '22 23:10

Emma


All solutions posted here, and all of the solutions I've seen on the web involves the use of third-party apps or the solution you already have.

I agree with @Phillip, there is no easier way to do what you want, even with the use of third-party apps it would require some work in order to adapt it to your purposes.

If you have many models that needs this behaviour, just implement a pre_save signal and write that code only once.

I recommend you to read Django Signals too, I'm sure you'll find it very interesting.

Very simple example:

from django.db.models.signals import pre_save
from django.dispatch import receiver

@receiver(pre_save, sender=Product)
def my_signal_handler(sender, instance, **kwargs):
    """
    Sender here would be the model, Product in your case.
    Instance is the product instance being saved.
    """
    # Write your solution here.
like image 41
Raydel Miranda Avatar answered Oct 05 '22 22:10

Raydel Miranda