#python #django #django-models
#python #django #django-модели
Вопрос:
Я немного смущен этим, я, кажется, не нахожу точного ответа на эту проблему, не уверен, какой подход будет безопаснее для этого.
У меня есть родительская модель и 2 дочерние модели, я использую формы django, чего я хочу, так это заполнить 2 дочерние модели всякий раз, когда родительское поле является, я имею в виду, они выглядят следующим образом:
class Parent(models.Model):
field1 = models.CharField()
field2 = models.CharField()
field3 = models.CharField()
class Child1(Parent):
pass
class Child2(Parent):
pass
Поскольку я не хочу / нуждаюсь в создании новых полей в дочерних классах, все будет унаследовано от родительского, я могу без проблем использовать родительские поля в admin или forms.
Но чего я на самом деле хочу, так это всякий раз, когда Parent
поля заполняются и сохраняются в БД, те же поля (или данные) также должны сохраняться в Child1
и Child2
.
Есть идеи о том, как этого добиться?
Комментарии:
1. Поскольку вы специализируете свою родительскую модель, обычно вы хотите создавать объекты из дочерних моделей, выполнение этого позволит вам получить доступ к этим объектам как к экземплярам как родительской, так и дочерней моделей.
2. Но если вы создадите объект из родительской модели, django не сможет узнать, имеет ли этот созданный объект тип child1 или child2.
3. Более формально в ООП следующее предположение: (тип(child_obj) == Parent) верно, но это предположение: (тип(parent_obj) == SomeChild) является ложным.
4. Вероятно, вы могли бы использовать подход, который работает так же хорошо для ваших целей без дублирования (трипликации?) данные, раздувающие вашу базу данных и вызывающие головные боли в дальнейшем.
Ответ №1:
Простое решение — переопределить save
метод, например:
from django.db import models
from django.forms import model_to_dict
class Parent(models.Model):
field1 = models.CharField(max_length=5)
field2 = models.CharField(max_length=5)
field3 = models.CharField(max_length=5)
def save(self, *args, **kwargs):
if not self.pk and self.__class__.__name__ == 'Parent':
Child1.objects.create(**model_to_dict(self))
Child2.objects.create(**model_to_dict(self))
super().save(*args, **kwargs)
но вы должны понимать, что после выполнения такого кода вы получите тройные экземпляры внутри родительской модели:
for _ in range(4):
Parent.objects.create(field1='dsad', field2='aa', field3='dd')
и:
Child1.objects.count()
4
Child2.objects.count()
4
но
Parent.objects.count()
12
Комментарии:
1. Хотя это решение синтаксически правильное, но оно семантически неверно, поскольку нарушает основные концепции ООП.
2. я так не думаю, потому что жизнь — это нечто большее, чем ООП
3. Хорошо, но вся идея ООП заключается в том, чтобы вдохнуть жизнь в кодирование, например, в ООП вместо того, чтобы говорить «переменная» и «операции», мы говорим «атрибут», «поведение».