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'


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,
# ...

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.


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.


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 .


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)

3

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

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL


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


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

0

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


-3

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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.