2

The common pattern for checking if an object is new is testing for:

self.pk is not None

As described in In a django model custom save() method, how should you identify a new object?

But it's not true when the oject is in one-to-one relation to some other object, say:

class X(models.Model):
     bla = models.OneToOneField(Bla)

Then if I want to create this object instance and save it to database I have do this:

x = X(bla=someBla)
x.save()

And x.pk is not null but x.pk = someBla.pk from the very begining.

So is there any posssibility to check if such an object is new or edited?

Community
  • 1
  • 1
mnowotka
  • 16,430
  • 18
  • 88
  • 134

2 Answers2

1
new  =  not bool(X.objects.filter(pk=self.pk).count())
mnowotka
  • 16,430
  • 18
  • 88
  • 134
-1

self.pk in save method will be None in this case, but make sure that you're checking this before calling super.save() in the save() method of class X.

DhhJmm
  • 429
  • 2
  • 10
  • def save(self, force_insert=False, force_update=False, *args, **kwargs): print ("pk=%s") % self.pk Never shows None, so it's not true. – mnowotka Feb 22 '13 at 12:16
  • Sorry, my bad. Why not use ForeignKey with unique=True? [See the differences](http://stackoverflow.com/a/5891861/912039). As to why this happens, according to an answer in that thread, OneToOneField represents composition, so it makes sense to assign the primary key of the related object upon instantiation. – DhhJmm Feb 22 '13 at 13:23
  • Because I would need to have additional id column somewere. I'm working with lagacy database and I can't just change OneToOne to ForeignKey. – mnowotka Feb 22 '13 at 13:32
  • 1
    In that case, the only option is to query the database in the save method to see if the object exists, and act accordingly (X.objects.get(pk=self.pk) and catch DoesNotExist). – DhhJmm Feb 22 '13 at 14:48
  • Almost there, but instead of get I'll be using filter.count() to avoid raising exceptions. – mnowotka Feb 28 '13 at 10:36