Django 1.8 user manager and .create () method are not used .update_or_create ()

I have two linked instances that should always be created together. I would like to do this without using signals or override the save() model method.

 class Car(models.Mode): make = models.CharField(max_length=32) model = models.CharField(max_length=32) class Meta: unique_together = ('make', 'model',) objects = CarManager() class CarProfile(models.Model): car = models.OneToOneField(Car) last_checkup = models.DateTimeField(blank=True, null=True) 

I created a custom CarManager that overrides models.Manager.create () to ensure that CarProfile is created when creating the car:

 class CarManager(models.Manager): def create(self, **kwargs): with transaction.atomic(): car = self.model(**kwargs) car.save(force_insert=True) CarProfile.objects.create(car=car) return car 

When I call Car.objects.create(make='Audi', model='R8') , a new Car instance is created and its corresponding CarProfile. However, when I try to create a new car using Car.objects.update_or_create(make='Audi', model='R8') or Car.objects.get_or_create(make='Audi', model='R8') , in both In cases, a Car instance is created, but the corresponding CarProfile is not created.

Why don't update_or_create and get_or_create call the expected CarProfile instance when I specified this behavior in a custom create() method ?

It seems that both of these methods call the create() class from QuerySet instead of my custom one.

+7
django django-models
source share
2 answers

The Django Manager class is actually a QuerySet that has been restored to Manager . What if you implement create on a QuerySet and then create Manager from this?

 class CarQuerySet(models.QuerySet): def create(self, **kwargs): with transaction.atomic(): car = self.model(**kwargs) car.save(force_insert=True) CarProfile.objects.create(car=car) return car 

Then Car :

 class Car(models.Mode): make = models.CharField(max_length=32) model = models.CharField(max_length=32) class Meta: unique_together = ('make', 'model',) objects = CarQuerySet.as_manager() 
+3
source share

The actual reason that overriding create does not work in this case is because you need to override the update_and_create and get_or_create , as well as the create methods, to influence their behavior.

+2
source share

All Articles