Ich habe zwei verwandte Instanzen, die immer zusammen erstellt werden sollten. Ich möchte dies tun, ohne Signale zu verwenden oder die save()
Methode des Modells zu überschreiben.Django 1.8 benutzerdefinierter Manager und .create() -Methode wird nicht von .update_or_create() verwendet
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)
Ich habe eine benutzerdefinierte CarManager erstellt, die models.Manager.create überschreibt(), um die Schaffung von CarProfile, um sicherzustellen, wenn ein Auto angelegt:
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
Als ich Car.objects.create(make='Audi', model='R8')
nennen, ein neues Auto Instanz und sein entsprechendes CarProfile wird wie erwartet erstellt. Wenn ich jedoch versuche, ein neues Auto mit Car.objects.update_or_create(make='Audi', model='R8')
oder Car.objects.get_or_create(make='Audi', model='R8')
zu erstellen, wird in beiden Fällen eine Car-Instanz erstellt, aber kein entsprechendes CarProfile erstellt.
Warum nicht update_or_create
und get_or_create
produziert das erwartete CarProfile Beispiel, wenn ich dieses Verhalten in den benutzerdefinierten create() method
angegeben habe?
Es scheint, dass diese beiden Methoden die create()
Klasse von QuerySet
statt meiner benutzerdefinierten aufrufen.
Ich habe bemerkt, wie ein Manager wirklich von 'BaseManager.from_queryset (QuerySet)' vererbt wird. Ich kann falsch liegen, aber es scheint, ['from_queryset'] (https://goo.gl/1L0x8N) und [' _get_queryset_methods'] (https://goo.gl/uEssIf) eine Ad-hoc-Klasse für Manager zu erstellen Unterklasse, die über beliebige Methoden in 'QuerySet' kopiert, die nicht in 'BaseManager' definiert sind. Meine 'CarManager'-Klasse unterklassifiziert dann diese Ad-hoc-Klasse, so dass ich verwirrt bin, warum 'create' das' QuerySet' nicht nur für' update_and_create' und 'get_or_create' überschreibt. – lajitong
Auch @Nathan Villaescusa, danke für Ihre Antwort. Ich habe am Ende ein benutzerdefiniertes "CarQuerySet" erstellt und eine Instanz davon in "get_queryset" von "CarManager" (ich habe andere Manager-Methoden dort) zurückgegeben. 'update_and_create' und' get_or_create' haben jetzt das korrekte Verhalten. Aber ich frage mich immer noch, warum meine vorherige Implementierung nicht funktioniert hat. – lajitong