Django 1.8自定义管理器和.create()方法未被.update_或_create()使用
我有两个应该一起创建的相关实例。我希望在不使用信号或覆盖模型的Django 1.8自定义管理器和.create()方法未被.update_或_create()使用,django,django-models,django-1.8,Django,Django Models,Django 1.8,我有两个应该一起创建的相关实例。我希望在不使用信号或覆盖模型的save()方法的情况下执行此操作 我创建了一个自定义CarManager,它覆盖models.Manager.create()以确保在创建汽车时创建CarProfile: class CarManager(models.Manager): def create(self, **kwargs): with transaction.atomic(): car = self.model(**
save()
方法的情况下执行此操作
我创建了一个自定义CarManager,它覆盖models.Manager.create()以确保在创建汽车时创建CarProfile:
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
当我调用Car.objects.create(make='Audi',model='R8')
时,会按预期创建一个新的Car实例及其相应的CarProfile。但是,当我尝试使用Car.objects.update\u或\u create(make='Audi',model='R8')
或Car.objects.get\u或\u create(make='Audi',model='R8')
创建新车时,在这两种情况下都会创建一个汽车实例,但不会创建相应的CarProfile
当我在自定义create()方法中指定了预期的CarProfile实例时,为什么不创建并生成该实例?
这两个方法似乎都是从
QuerySet
类调用create()
,而不是调用我的自定义类。Django的Manager
类实际上是一个QuerySet
类,它已经进入了Manager
。如果在QuerySet
上实现create
,然后从中构建管理器,会怎么样
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
然后汽车
是:
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()
重写create
在本例中不起作用的实际原因是,您需要重写update\u和\u create
以及get\u或\u create
方法以及create
来影响它们的行为。只是想澄清一下,这个问题在Django v1.8a1中已经解决了。因此,现在get\u或\u create
和update\u或\u create
将按预期调用managerscreate
方法
我注意到管理器实际上是从BaseManager.from_queryset(queryset)
继承而来的。我可能错了,但它似乎为Manager创建了一个特殊的类,以便在QuerySet
中复制BaseManager
中未定义的任何方法。然后,我的CarManager
类对这个特殊类进行了子类化,所以我不明白为什么create
没有覆盖QuerySet
中的一个,只用于update\u和\u create
和get\u或\u create
。另外,@Nathan Villaescusa,感谢您的回复。我确实创建了一个自定义的CarQuerySet
,并在CarManager
的get_queryset
中返回了它的一个实例(我还有其他管理器方法)<代码>更新和创建
和获取或创建
现在具有正确的行为。但我仍然想知道为什么我以前的实现不起作用。为什么不覆盖save
,因为这似乎是它们的共同点。
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()