integrating variable in FilePathField path attribute

Hi all,

I’m brand new to django, and I’m stuck on something so simple (?) I’m pretty confused to ask…
Extract from model.py :

inv_app_fs = FileSystemStorage(location="/inventaires_ansible")

class Inventaire(models.Model):
    inventaire_name = models.CharField(max_length=20)
    inv_last_modif = models.DateTimeField("derniere modif")
    #inv_file_path = model.FilePathField(path="inv_app_fs/{ self.inventaire_name }.ok" 
    def __str__(self):
        return self.inventaire_name

My issue is with the commented line :
How to pass the varables (inv_app_fs and self.inventaire_name), concataned to the string : “.ok” (dot is important, as you can guess).
Should I wrap variables into ‘{’, or ‘{{’, or ?..

I tried in a shell with things like :

inv_app_fs = FileSystemStorage(location="inventaires_ansible")
path = default_storage.save( inv_app_fs.location + "/fst.ok", ContentFile(b"iHello world"))

(with or without brackets, double brackets, and all kind of combinations, without any success).

The goal, whichever module I use, is to be able to store dynamic file path in the model, or to access the file using dynamic path.

If someone could help (I red a lot of documentations, examples… but never found one with variables).

Regards

Welcome @E.T !

A model field can define a default, but the values are assigned to the instance of that model.

It’s actually not any different than any other field in that regard. You can assign a value to the inv_file_path field the same way you assign a value to the inventaire_name field. They really aren’t very different. (At the database layer, it’s just another CharField.)

Have you worked your way through either (or both) of the Official Django Tutorial and the Django Girls Tutorial? If not, you should.

Hi KenWhitesell,

Thanks for your answer.
My issue is not “how to assign a value” to the attribute, but how should I use this value in the path=argument ?
It’s a syntax issue for :

path="inv_app_fs/{ self.inventaire_name }.ok"

Should I use brackets around variable names, or double, or nothing ? For now, in tests I did with shell commands, it created directory named inv_app_fs (or even {{ inv_app_fs }}), but not /inventaires_ansible.

Yes, I’m already following the official tutorial, adapting it to my needs. I guess this is a basic point, but I found the answer anywhere.

Could you, for example, give me an example of working line for :

inv_file_path = model.FilePathField(path="{ inv_app_fs }/{ self.inventaire_name }.ok") 

(replacing { inv_app_fs } and { self.inventaire_name } with the right syntax)

You do not do this in the model definition.

If it’s dynamic, it’s done on the instance of the model.

Django models are not typical Python classes. They’re heavily meta-class driven such that the Model definition ends up creating a class for the model. The field definitions do not directly create a “field value” attribute.

You need to not think of Models the same way you would think of any other type of Python class. For example, one of the things you should never do is override the __init__ method of a model. There are other hooks available for doing the types of things you might think of doing there.

If you’re interested in more of the details, see the docs starting with Models | Django documentation | Django

Yeah,

That’s exactly what I want to get : a dynamic definition that create a personalized static one for each instance.

I finally found a cleaner way to do (I guess) : create a method for this model, returning what I need.

def get_inv_file_path(self):
    return inv_app_fs.location + "/" + self.inventaire_name + ".ok"

It works just like I wanted to !

Yea, that’ll work. It also saves having that extra field in the model.