Django ORM: дочерние поля и значения не наследуются. Объекты дублируются. (Используя Django интерфейс администратора) - PullRequest
1 голос
/ 04 мая 2020

Я пытаюсь иметь различные блюда (Pizza, Subs и др. c), которые наследуются от общего (конкретного) родителя class Dish. (Логически, у меня нет никаких причин для того, чтобы он был конкретным, за исключением того, что у него были трудности с его реализацией).

Каждая пицца (или другой конкретный ди sh) соответствует ровно одному идентификатору ди sh (реализованному как FK здесь), и каждый di sh (ID) - ровно одна пицца.

Я новичок в этом, но, насколько я понимаю, общие поля (имя, тип, размер, размер и di sh) Идентификатор (PK для Dish = FK dish_id для Pizza)) в Dish, а также их значения наследуются дочерними элементами, такими как Pizza. Вот вам и теория.

Теперь я реализовал классы, как показано ниже. А затем я использую интерфейс администратора Django для создания объектов, но, вопреки ожиданиям, когда я создаю объект Dish типа 'Pizza', автоматически создается объект Pizza. Теперь, когда я go в этот Pizza объект, поля имени, типа, цены и размера остаются пустыми. Разве они не должны быть установлены, когда я выбираю атрибут Pizza dish в качестве Dish -объекта, который я только что создал?

А также когда я начинаю с создания Pizza, выбирая соответствующий родитель (или создание его в интерфейсе администратора Django), мне нужно заполнить все общие поля дважды (один раз в Dish, а затем снова в Pizza).

И в зависимости от того, как я это делаю итак, я получаю повторяющиеся записи: 1 пицца для объекта Pizza, который я создал, и 1 пицца для типа Di sh, который я создал для этой пиццы. (то же самое, 1 di sh для созданного di sh и 1 di sh для пиццы, которую я создал).

В чем моя ошибка и является ли это недостатком дизайна или способ создания записей базы данных?

class Dish(models.Model):
  PIZZA = 'PIZZA'
  SUB = 'SUB'
  PASTASALAD = 'PASTASALAD'
  PLATTER = 'PLATTER'
  TYPE_CHOICES = ( (PIZZA, 'Pizza'), (SUB, 'Sub'), (PASTASALAD, 'PastaSalad'), (PLATTER, 'Platter') )
  name = models.CharField(max_length=64, blank=True) # blank makes name optional
  type = models.CharField(max_length=64, choices=TYPE_CHOICES, blank=True)
  size = models.CharField(max_length=1, choices=SIZE_CHOICES, default=SMALL, blank=True)
  price = models.DecimalField(max_digits=6, decimal_places=2, default=None)

class Pizza(Dish):
  dish = models.ForeignKey(Dish, on_delete=models.CASCADE, related_name="dish_id_pizza")
  REGULAR = 'REGULAR'
  SICILIAN = 'SICILIAN'
  STYLE_CHOICES = ( (REGULAR, 'Regular'), (SICILIAN, 'Sicilian'),)
  style = models.CharField(max_length=7, choices=STYLE_CHOICES, default=REGULAR)
  topping_count = models.IntegerField(default=0, validators=[MaxValueValidator(5), MinValueValidator(0)])

1 Ответ

1 голос
/ 04 мая 2020

Используйте отношение OneToOne, так как вам нужно ровно одно.

class Pizza(models.Model):
    dish = models.OneToOneField(Dish, on_delete=models.CASCADE, related_name="dish_id_pizza")

Это должно решить проблему с дублированием и заполнить себя и пустые поля.

Примечание: что вы также должны написать Методы str dunder позволяют легко отслеживать каждое поле модели. как это.

def __str__(self):
    return f"{self.name}"
...