physicalattraction
physicalattraction

Reputation: 6858

Save model tries to create new object

I have the following two Django models:

class A:
    uuid = CharField(primary_key=True)
    code = CharField(unique=True)

class B:
    uuid = CharField(primary_key=True)
    a = ForeignKey(A, related_name='bs')

    def save(**kwargs):
        self.a.save(**kwargs)
        super(B, self).save(**kwargs)

If I want to use them in a test case and write this function:

def setUp():
    a = A.objects.create(uuid='a')
    b = B.objects.create(uuid='b', a=a)

I get the following error:

UNIQUE constraint failed: app_name_a.code

It looks like that in the save method of B, it tries to create another A with the same values instead of updating the existing instance. Why would this be so? I am using Python 3.5 and Django 1.8.14.

By the way: the reason I want to save the parent is that I have functionality in the save method that is updating an updated_at timestamp.

Upvotes: 2

Views: 54

Answers (1)

Ozgur Vatansever
Ozgur Vatansever

Reputation: 52093

The problem is in kwargs you passed into A.save():

self.a.save(**kwargs)

If you look at the documentation, you'll see force_insert is sent True (because A is being created at the moment) when you try to save B so Django won't check if self.a has already been created because you are passing force_insert as True to self.a.save() as well.

To fix this, you should not pass **kwargs in order to let Django make the decision on creating or updating self.a:

def save(self, *args, **kwargs):
    self.a.save()
    super(B, self).save(*args, **kwargs)

Upvotes: 1

Related Questions