I have a problem in one of my models. I'm uploading an image, and I want to store the id (pk in the database table) but I need to know at which point Django will have access to self.id
.
models.py
class BicycleAdItemKind(MPTTModel): def url(self, filename): pdb.set_trace() url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (self.id, filename) return url def item_kind_image(self): return '<img align="middle" src="/media/%s" height="60px" />' % self.image item_kind_image.allow_tags = True # Bicicleta completa, Componentes para bicicleta, Acessorios para ciclista n_item_kind = models.CharField(max_length=50) parent = TreeForeignKey('self', null=True, blank=True, related_name='children') description = models.TextField(null=True, blank=True) image = models.ImageField(upload_to=url, null=True, blank=True) date_inserted = models.DateTimeField(auto_now_add=True) date_last_update = models.DateTimeField(auto_now=True) def __unicode__(self): return self.n_item_kind class MPTTMeta: order_insertion_by = ['n_item_kind']
The problem is in the url()
method; I can only get self.id
when updating an object, I don't get the self.id
when creating a new object. How can I modify this model so that I get self.id
when creating a new object?
With the current code, when I'm creating a new object I will end up with a url like:
MultimediaData/HelpAdImages/ItemKind/None/somefile.jpg
And I need to have something like:
MultimediaData/HelpAdImages/ItemKind/35/somefile.jpg
Any clues?
Django will create or use an autoincrement column named id by default, which is the same as your legacy column.
def str(self): is a python method which is called when we use print/str to convert object into a string. It is predefined , however can be customised.
To save changes to an object that's already in the database, use save() . This performs an UPDATE SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() .
By default, Django adds an id field to each model, which is used as the primary key for that model. You can create your own primary key field by adding the keyword arg primary_key=True to a field. If you add your own primary key field, the automatic one will not be added.
You might need to save this file/instance twice:
You can use a post_save signal on the model that looks for the created flag, and re-saves the instance updating the url (and moving/renaming the file as necessary), since the instance will now have an ID. Make sure you only do this conditioned on created, though, otherwise you will continuously loop in saving: saving kicks off a post-save signal, which does a save, which kicks off a post-save signal...
See https://docs.djangoproject.com/en/dev/ref/signals/#post-save
If it's a new object, you need to save it first and then access self.id, because
"There's no way to tell what the value of an ID will be before you call save(), because that value is calculated by your database, not by Django."
Check django's document https://docs.djangoproject.com/en/dev/ref/models/instances/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With