Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django ORM继承:您试图添加一个不可为空的字段';碟形ptr';在没有默认值的情况下将其添加到[…]_Python_Django_Django Models_Orm - Fatal编程技术网

Python Django ORM继承:您试图添加一个不可为空的字段';碟形ptr';在没有默认值的情况下将其添加到[…]

Python Django ORM继承:您试图添加一个不可为空的字段';碟形ptr';在没有默认值的情况下将其添加到[…],python,django,django-models,orm,Python,Django,Django Models,Orm,我正在开发一个餐厅应用程序(Django/Python的新手)。我希望有一个父类Dish,它将包含一些计数器或ID,为Dish的子类的每个实例递增。例如比萨饼、意大利面等具有不同特征和关系的菜肴。我试图使Dish具体化,因为在这种情况下,我认为我只需要访问Dish的主键,这将给每个菜单项一个Dish-ID。 但是,我不知道如何正确地修复遇到的错误:您正在尝试添加一个不可为空的字段“意大利面” 以下是相关的代码片段: class Dish(models.Model): pass # shoul

我正在开发一个餐厅应用程序(Django/Python的新手)。我希望有一个父类Dish,它将包含一些计数器或ID,为Dish的子类的每个实例递增。例如比萨饼、意大利面等具有不同特征和关系的菜肴。我试图使
Dish
具体化,因为在这种情况下,我认为我只需要访问
Dish
的主键,这将给每个菜单项一个Dish-ID。 但是,我不知道如何正确地修复遇到的错误:
您正在尝试添加一个不可为空的字段“意大利面”

以下是相关的代码片段:

class Dish(models.Model):
  pass # should automatically generate PK, right?

class Pasta(Dish):
  name = models.CharField(max_length=64, primary_key=True)
  price = models.DecimalField(max_digits=6, decimal_places=2)

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

class Pizza(Dish):
  sizestyle = models.CharField(max_length=4, choices=SIZESTYLE_CHOICES, default=SMALL_REGULAR)
  topping_count = models.IntegerField(default=0, validators=[MaxValueValidator(5), MinValueValidator(0)])
  price = models.DecimalField(max_digits=6, decimal_places=2)

  def __str__(self):
    return f"Price for {self.sizestyle} pizza with {self.topping_count} toppings: ${self.price}"

class Sub(Dish):
  name = models.CharField(max_length=64, primary_key=True)
  price_category = models.ForeignKey(SubPrice, on_delete=models.DO_NOTHING, related_name="sub_price_category")

  def __str__(self):
    return f"{self.name}, Price Category: {self.price_category}"

class Platter(Dish):
  name = models.CharField(max_length=64, primary_key=True)
  price_large = models.DecimalField(max_digits=6, decimal_places=2, default=0)
  price_small = models.DecimalField(max_digits=6, decimal_places=2, default=0)

  def __str__(self):
    return f"{self.name} price: Large ${self.price_large}, Small ${self.price_small}"

如果您想从
Dish()
继承,但数据库中没有它,可以执行以下操作:

当你们使用它的时候,它只会继承盘子里的任何东西。您将不会在数据库中将Dish视为一个表

如果确实要将其用作父类,则需要告诉子类Dish是父类:


这将在数据库中为菜肴创建一个id,当创建比萨饼时,它将引用菜肴的id(pk)。

如果数据库中已经有意大利面或比萨饼,他们需要知道与哪个具体菜肴关联。如果您还没有重要数据,请删除db或
python manage.py migrate dish_app zero
,然后删除并重新进行迁移,您的设计是错误的。@Anna您的设计问题是,您正在将每种碟片一对一地映射到一个特定的模型—您正在尝试将用户对数据的看法直接转换到db模式—而不是进行更深入的分析,并设计一个可以描述各种碟片(现有和未来)的模式进入一个统一的模式。这个模式当然不是用户(最终用户和站点管理员)如何查看数据的简单映射,需要一些中间域层来将db模式转换为域对象,但大多数非平凡的应用程序都是这样。例如,“Platter”类有两个价格字段,分别用于小部分和大部分。这实际上意味着一道菜可以有一个或多个价格,因此您应该有一个带有“限定符”(即“小”、“大”等)的“价格”实体,并在“菜”实体上有一个FK。使用这种方法,当餐厅决定添加“中等”或“特大号”的部分时,他们只需在后端进行配置。“比萨没有名称”=>将菜名设置为可选,或者将菜名命名为“比萨”。“比萨饼的价格是基于#配料的计算”=>然后你需要一个额外的间接层次-例如一个“Pricer”对象(),它知道如何计算一道菜的价格(我在我当前的应用程序中也有同样的情况,这就是我实现解决方案的方式)。请注意,我并不是说您当前的设计根本不起作用,也不是说我建议的方法“更简单”(实际上更复杂);-)非常感谢。我尝试了后者,但“Pizza.dish”的反向查询名称与“Pizza.dish\u ptr”的反向查询名称发生冲突。提示:在“Pizza.dish”或“Pizza.dish”的定义中添加或更改一个相关的\u name参数——因此我添加了一个相关的名称。但是当再次运行makemigrations时,我再次发现
您试图在没有默认值的情况下向意大利面添加一个不可为空的字段'dish'。如果它引用的是
Dish
中自动生成的PK,为什么它需要一个默认值?您得到最后一个错误的原因是因为您是对的
PK
是一个不可为空的字段。这意味着数据库中的数据已经由
dish\u ptr
表示,因此在运行迁移时,Django在添加
dish=models.ForeignKey…
之前不知道dish是Pizza的主键。我目前知道的唯一解决方法是删除数据库中的数据,然后运行迁移。我获取了您的模型,运行了迁移,添加了数据,然后根据我的示例更新了模型,您可以通过运行
python manage.py dumpdata-o path/to/output/file.json
来挽救数据,但在运行
python manage.py loaddata path/to/file.json
之前,您需要对json文件进行一些编辑,否则会出现另一个错误,由于文件中的
dish_ptr
引用。
class Dish(models.Model):
    # your model structure

    class Meta:
        abstract = True

class Pizza(Dish):
    # your model structure
class Dish(models.Model):
    pass

class Pizza(models.Model):
    dish = models.ForeignKey(Dish, on_delete=models.CASCADE)
    # other model structure