尝试在子表格有记录后添加父表格时,出现TypeError: __init__()缺少1个必需的位置参数'on_delete'错误。

132

我在sqlite数据库中有两个类,一个名为Categorie的父表和一个称为Article的子表。我首先创建了子表类并添加了一些条目。因此,一开始我有这个:

class Article(models.Model):
    titre=models.CharField(max_length=100)
    auteur=models.CharField(max_length=42)
    contenu=models.TextField(null=True)
    date=models.DateTimeField(
        auto_now_add=True,
        auto_now=False,
        verbose_name="Date de parution"
    )

    def __str__(self):
        return self.titre

我添加了父表后,现在我的models.py看起来像这样:

from django.db import models

# Create your models here.
class Categorie(models.Model):
    nom = models.CharField(max_length=30)

    def __str__(self):
        return self.nom


class Article(models.Model):
    titre=models.CharField(max_length=100)
    auteur=models.CharField(max_length=42)
    contenu=models.TextField(null=True)
    date=models.DateTimeField(
        auto_now_add=True,
        auto_now=False,
        verbose_name="Date de parution"
    )
    categorie = models.ForeignKey('Categorie')

    def __str__(self):
        return self.titre

当我运行python manage.py makemigrations <my_app_name>时,我收到了这个错误:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\lislis\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django-2.0-py3.5.egg\django\core\management\__init__.py", line 354, in execute_from_command_line
    utility.execute()
  File "C:\Users\lislis\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django-2.0-py3.5.egg\django\core\management\__init__.py", line 330, in execute
    django.setup()
  File "C:\Users\lislis\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django-2.0-py3.5.egg\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\lislis\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django-2.0-py3.5.egg\django\apps\registry.py", line 112, in populate
    app_config.import_models()
  File "C:\Users\lislis\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django-2.0-py3.5.egg\django\apps\config.py", line 198, in import_models
    self.models_module = import_module(models_module_name)
  File "C:\Users\lislis\AppData\Local\Programs\Python\Python35-32\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
  File "C:\Users\lislis\Django\mon_site\blog\models.py", line 6, in <module>
    class Article(models.Model):
  File "C:\Users\lislis\Django\mon_site\blog\models.py", line 16, in Article
    categorie = models.ForeignKey('Categorie')
TypeError: __init__() missing 1 required positional argument: 'on_delete'

我在stackoverflow上看到了一些类似的问题,但似乎不是同一个问题:__init__()缺少1个必需的位置参数'quantity'


3
你使用的是哪个版本的Django? - alfonso.kim
3
您对这里有什么疑惑?正如错误清楚地表明的那样,ForeignKey需要一个必需参数 on_delete。请参阅文档 - Daniel Roseman
我不需要on_delete参数,这是必须的吗? - Christian LSANGOLA
1
@jochri3 是的,“必需位置参数”意味着它是强制性的。请查阅文档,找出最适合您需求的选项。 - cezar
你尝试阅读 models.ForeignKey 的文档以了解如何使用它了吗?这实际上是关于 Django API 的问题,还是关于如何阅读和理解错误消息的问题? - Karl Knechtel
12个回答

228

您可以像这样更改类Article的属性categorie

categorie = models.ForeignKey(
    'Categorie',
    on_delete=models.CASCADE,
)

错误应该会消失。

最终你可能需要另一个on_delete的选项,请查阅文档以获取更多详细信息:

参数 -- 模型字段参考 -- Django 文档

正如你在评论中所述,你对on_delete没有任何特殊要求,你可以使用DO_NOTHING选项:

# ...
on_delete=models.DO_NOTHING,
# ...

3
在Django < 2中,on_delete=models.CASCADE是默认选项。 - Peter F
不起作用。2023年。 - biscuit_delicious

50
自 Django 2.x 版本开始,on_delete 是必填项。
参见Django 文档

自版本1.9起已弃用:在Django 2.0中,on_delete将变为必需参数。 在旧版本中,默认情况下为CASCADE。


17

自Django 2.0版本起,ForeignKey字段需要两个位置参数:

  1. 要映射的模型
  2. on_delete参数
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

以下是可以在on_delete中使用的一些方法:

  1. CASCADE

级联删除。Django模拟SQL约束ON DELETE CASCADE的行为,同时还会删除包含ForeignKey的对象。

  1. PROTECT

通过引发ProtectedError(django.db.IntegrityError的子类)来防止删除所引用的对象。

  1. DO_NOTHING

不采取任何措施。如果您的数据库后端执行引用完整性,则此操作将导致IntegrityError,除非您手动向数据库字段添加SQL ON DELETE约束。

您可以通过阅读文档了解更多关于on_delete的内容。


14

从Django 2.0开始,on_delete是必需的:

user = models.OneToOneField(User, on_delete=models.CASCADE)

如果删除User,则将删除子表数据。有关详细信息,请查看Django文档。


2
为什么这个答案与安德烈之前提供的信息不一致? - Samuel Dauzon

4

如果您正在使用外键,那么必须使用“on_delete = models.CASCADE”,因为它将在从父表中删除原始元素后消除所产生的复杂性。就是这么简单。

categorie = models.ForeignKey('Categorie', on_delete=models.CASCADE)

4
自 Django 1.9 版本以后,on_delete 参数成为了必选项,即从 Django 2.0 开始。在旧版本中,默认为 CASCADE。因此,如果您想要复制早期版本中使用的功能,请使用以下参数。
categorie = models.ForeignKey('Categorie', on_delete = models.CASCADE)

这将具有与早期版本中相同的效果,而不需要明确指定。

官方文档关于 on_delete 的其他参数的说明


3

以下是可用的选项,如果有助于任何人进行on_delete操作

CASCADE级联删除、DO_NOTHING不做任何操作、PROTECT保护、SET设置、SET_DEFAULT设置默认值、SET_NULL设置为NULL


3
如果您不知道要输入哪个选项参数,只希望在迁移之前保留默认值,比如on_delete=None

on_delete=models.CASCADE

这是旧版本中的代码片段:
if on_delete is None:
    warnings.warn(
        "on_delete will be a required arg for %s in Django 2.0. Set "
        "it to models.CASCADE on models and in existing migrations "
        "if you want to maintain the current default behavior. "
        "See https://docs.djangoproject.com/en/%s/ref/models/fields/"
        "#django.db.models.ForeignKey.on_delete" % (
            self.__class__.__name__,
            get_docs_version(),
        ),
        RemovedInDjango20Warning, 2)
    on_delete = CASCADE

2
自Django 2.0版本起,"models.ForeignKey()""models.OneToOneField"必须有"on_delete"属性。例如以下代码:

"models.ForeignKey()":

categories = models.ForeignKey('Category', on_delete=models.CASCADE)

"models.OneToOneField":

categories = models.OneToOneField('Category', on_delete=models.PROTECT)

0

我曾经遇到过类似的问题,通过在ForeignKey中添加这两个参数解决了问题:

null=True, on_delete=models.SET_NULL


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接