如何在 Django 中添加多态类?

Posted

技术标签:

【中文标题】如何在 Django 中添加多态类?【英文标题】:How do I add a polymorphic class in Django? 【发布时间】:2020-06-19 18:19:28 【问题描述】:

我正在尝试在 django 中申请一家餐厅;我必须为不同类型的项目创建一个菜单,所有这些不同类型的项目本质上必须是产品,这样我才能将该产品添加到用户的相应购物车中。这是我的菜单项:

from django.db import models
from django.contrib.auth.models import User

class Product(models.Model):
    price = models.DecimalField(decimal_places=2, max_digits=10)

class Pizza(Product):
    pizzatype = models.CharField(max_length=15)
    extras = models.TextField(max_length=50)
    size = models.CharField(max_length=10)

class Subs(Product):
    name = models.TextField(max_length=64)
    size = models.CharField(max_length=10)

class DinnerPlatters(Product):
    name = models.TextField(max_length=64)
    size = models.CharField(max_length=10)

class Pasta(Product):
    name = models.TextField(max_length=64)

class Salads(Product):
    name = models.TextField(max_length=64)

可以看出,我尝试从单个模型 Product 派生不同类型菜单项的模型,但是在运行 makemigrations 时,我在终端上收到以下消息:

You are trying to add a non-nullable field 'product_ptr' to dinnerplatters without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py

我尝试在谷歌上搜索我的问题的解决方案,但找不到合适的解决方案。

我是 Django 新手,这是我的第一个应用程序,因此我们将不胜感激任何有关如何解决我的问题的帮助或任何其他方法。

【问题讨论】:

【参考方案1】:

由于您的模型继承自产品的模型,因此您使用的是多表继承。现在多表继承会在继承模型和基本模型之间自动创建 OneToOneField 作为 classname_ptr,从产品模型继承的模型具有 product_ptr 字段。由于您的模型具有 product_ptr 字段,您应该为您之前保存的现有行添加默认值。

https://docs.djangoproject.com/en/3.0/topics/db/models/#multi-table-inheritance

【讨论】:

感谢您的回答;根据您的回答和文档,我尝试将以下行添加到从Product 类继承的每个类中:product_ptr = models.OneToOneField(Product, on_delete=models.CASCADE, parent_link=True, primary_key=True, default = None)。现在,我的 makemigrations 运行,但我现在在运行 migrate 时收到错误 django.db.utils.IntegrityError: The row in table 'orders_pizza' with primary key '1' has an invalid foreign key: orders_pizza.product_ptr_id contains a value '1' that does not have a corresponding value in orders_product.id. product_ptr = models.OneToOneField(Product, on_delete=models.CASCADE, parent_link=True, primary_key=True, null=True, blank=True) 你能试试这个吗? 在这样做时,我在所有型号上都得到了这个:orders.DinnerPlatters.product_ptr: (fields.E007) Primary keys must not have null=True.HINT: Set null=False on the field, or remove primary_key=True argument.。在尝试 null=False 或删除 primary_key=True 时,我得到与上次相同的完整性错误:django.db.utils.IntegrityError: The row in table 'orders_pizza' with primary key '1' has an invalid foreign key: orders_pizza.product_ptr_id contains a value '1' that does not have a corresponding value in orders_product.id.

以上是关于如何在 Django 中添加多态类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 中添加样式

Django:如何添加动态类以选择表单中的选项

如何将引导类添加到模板中的 Django CreateView 表单字段?

如何根据 Django 中当前基于类的通用视图模型向模板加载器添加路径

如何在 django 模板中获取类

Django Allauth - 如何将自定义 CSS 类添加到字段?