Сохранение тех же данных из родительской модели в дочерние элементы — Django 1.11

#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. Хорошо, но вся идея ООП заключается в том, чтобы вдохнуть жизнь в кодирование, например, в ООП вместо того, чтобы говорить «переменная» и «операции», мы говорим «атрибут», «поведение».