Abrufen von TypeError: __init __ () fehlt 1 erforderliches Positionsargument: 'on_delete', wenn versucht wird, eine übergeordnete Tabelle nach einer untergeordneten Tabelle mit Einträgen hinzuzufügen

89

Ich habe zwei Klassen in meiner SQLite-Datenbank, eine übergeordnete Tabelle mit dem Namen Categorieund die untergeordnete Tabelle mit dem Namen Article. Ich habe zuerst die untergeordnete Tabellenklasse erstellt und Einträge hinzugefügt. Also hatte ich zuerst folgendes:

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

Und nachdem ich die übergeordnete Tabelle hinzugefügt habe und jetzt meine so models.pyaussieht:

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

Wenn ich laufe python manage.py makemigrations <my_app_name>, erhalte ich folgende Fehlermeldung:

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'

Ich habe einige ähnliche Probleme im Stapelüberlauf gesehen, aber es scheint nicht dasselbe Problem zu sein: __init __ () fehlt 1 erforderliches Positionsargument: 'Quantität'

Christian Lisangola
quelle
3
Welche Version von Django benutzt du?
alfonso.kim
1
Also, worüber bist du hier verwirrt? Wie der Fehler eindeutig sagt, hat ForeignKey ein erforderliches Argument on_delete. Siehe die Dokumente .
Daniel Roseman
Ich brauche den on_deleteParameter nicht, ist er obligatorisch?
Christian Lisangola
@ jochri3 Ja, das erforderliche Positionsargument bedeutet, dass es obligatorisch ist. Überprüfen Sie die Dokumentation, um herauszufinden, welche Option Ihren Anforderungen am besten entspricht.
Cezar

Antworten:

160

Sie können die Eigenschaft categorieder Klasse folgendermaßen ändern Article:

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

und der Fehler sollte verschwinden.

Möglicherweise benötigen Sie eine andere Option on_deletefür. Weitere Informationen finden Sie in der Dokumentation:

https://docs.djangoproject.com/de/1.11/ref/models/fields/#django.db.models.ForeignKey

BEARBEITEN:

Wie Sie in Ihrem Kommentar angegeben haben, für die Sie keine besonderen Anforderungen haben on_delete, können Sie die folgende Option verwenden DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...
Cezar
quelle
41

Da ist Django 2.x on_deleteerforderlich.

Django-Dokumentation

Veraltet seit Version 1.9: on_delete wird in Django 2.0 zu einem erforderlichen Argument. In älteren Versionen wird standardmäßig CASCADE verwendet.

Andrey Zhilyakov
quelle
11

Ab Django 2.0 on_deleteist erforderlich:

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

Die untergeordneten Tabellendaten werden gelöscht, wenn der Benutzer gelöscht wird. Weitere Informationen finden Sie in der Django-Dokumentation.

Javed Gouri
quelle
1
Warum diese Antwort, während Andrey früher mit diesen Informationen antwortet?
Samuel Dauzon
8

Seit Django 2.0 erfordert das ForeignKey-Feld zwei Positionsargumente:

  1. das Modell, dem zugeordnet werden soll
  2. das on_delete-Argument
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Hier sind einige Methoden, die in on_delete verwendet werden können

  1. KASKADE

Kaskade wird gelöscht. Django emuliert das Verhalten der SQL-Einschränkung ON DELETE CASCADE und löscht auch das Objekt, das den ForeignKey enthält

  1. SCHÜTZEN

Verhindern Sie das Löschen des referenzierten Objekts, indem Sie ProtectedError, eine Unterklasse von django.db.IntegrityError, auslösen.

  1. NICHTS TUN

Nimm keine Aktion. Wenn Ihr Datenbank-Backend die referenzielle Integrität erzwingt, führt dies zu einem IntegrityError, sofern Sie dem Datenbankfeld nicht manuell eine SQL ON DELETE-Einschränkung hinzufügen.

Weitere Informationen zu on_delete finden Sie in der Dokumentation .

Thusitha Deepal
quelle
4

Wenn Sie einen Fremdschlüssel verwenden, müssen Sie "on_delete = models.CASCADE" verwenden, da dadurch die Komplexität beseitigt wird, die nach dem Löschen des ursprünglichen Elements aus der übergeordneten Tabelle entsteht. So einfach ist das.

categorie = models.ForeignKey('Categorie', on_delete=models.CASCADE)
Bala Kiswe
quelle
3

Hier sind verfügbare Optionen, wenn es jemandem bei on_delete hilft

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL

Tarun Behal
quelle
1

Post Django Version 1.9 wurde on_deletezu einem erforderlichen Argument, dh aus Django 2.0.

In älteren Versionen wird standardmäßig CASCADE verwendet.

Wenn Sie also die Funktionalität replizieren möchten, die Sie in früheren Versionen verwendet haben. Verwenden Sie das folgende Argument.

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

Dies hat den gleichen Effekt wie in früheren Versionen , ohne dass dies explizit angegeben wird.

Offizielle Dokumentation zu anderen Argumenten, die zu on_delete gehören

Optider
quelle
0

Wenn Sie nicht wissen, welche Option Sie eingeben sollen. Ich möchte nur den Standardwert wie on_delete=Nonevor der Migration beibehalten:

on_delete = models.CASCADE

Dies ist ein Code-Snippet in der alten Version:

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
HoangYell
quelle
0

Hatte ein ähnliches Problem, das durch Hinzufügen dieser beiden Parameter zu ForeignKey behoben wurde: null = True, on_delete = models.SET_NULL

Nir Tsabar
quelle
-3

Das hat bei mir funktioniert pip install django-csvimport --upgrade

Mayank Jaiswal
quelle
2
Wie beantwortet dies die Frage?
Cezar
Hallo Mayank. Sie haben wahrscheinlich etwas anderes getan, um diesen Fehler zu beheben, oder Sie verwenden eine frühere Version von Django.
Chris Dare
Dies wird gelöst, indem den Modellen ein Wert für das Argument "on_delete" zugewiesen wird.ForeignKey
Chris Dare
Sie verwenden Django vor Version 2. Weil alle späteren Versionen on_deleteeinen Zwang gemacht haben! In früheren Versionen war es standardmäßigon_delete = models.CASCADE
Optider