Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - How to get self.id when saving a new object?

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?

like image 649
André Avatar asked Jan 09 '13 12:01

André


People also ask

Does Django create ID automatically?

Django will create or use an autoincrement column named id by default, which is the same as your legacy column.

What is def __ str __( self in Django?

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.

How do I save an object in Django?

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() .

Does Django create ID field?

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.


2 Answers

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

like image 34
sbywater Avatar answered Sep 16 '22 16:09

sbywater


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/

like image 134
Qiang Jin Avatar answered Sep 17 '22 16:09

Qiang Jin