Ottenere TypeError: __init __ () manca 1 argomento posizionale richiesto: 'on_delete' quando si tenta di aggiungere la tabella padre dopo la tabella figlia con voci


92

Ho due classi nel mio database sqlite, una tabella padre denominata Categoriee la tabella figlia chiamata Article. Ho creato prima la classe della tabella figlio e ho aggiunto le voci. Quindi prima ho avuto questo:

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

E dopo aver aggiunto la tabella genitore, e ora il mio models.pyaspetto è questo:

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

Quindi, quando corro python manage.py makemigrations <my_app_name>, ottengo questo errore:

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'

Ho visto alcuni problemi simili in stackoverflow, ma sembra non essere lo stesso problema: __init __ () manca 1 argomento posizionale richiesto: 'quantity'


3
quale versione di django stai usando?
alfonso.kim

2
Allora, di cosa sei confuso qui? Come l'errore dice chiaramente, ForeignKey ha un argomento richiesto, on_delete. Vedi i documenti .
Daniel Roseman

Non ho bisogno del on_deleteparametro, è obbligatorio?
Christian Lisangola

@ jochri3 Sì, l' argomento posizionale richiesto significa che è obbligatorio. Controlla la documentazione per scoprire quale opzione si adatta meglio alle tue esigenze.
cezar

Risposte:


168

Puoi modificare la proprietà categoriedella classe in Articlequesto modo:

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

e l'errore dovrebbe scomparire.

Alla fine potresti aver bisogno di un'altra opzione per on_delete, controlla la documentazione per maggiori dettagli:

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

MODIFICARE:

Come hai affermato nel tuo commento, per i quali non hai requisiti speciali on_delete, puoi utilizzare l'opzione DO_NOTHING:

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

1
on_delete = models.CASCADE è l'impostazione predefinita in Django <2
Peter F il

46

Poiché Django 2.x, on_deleteè richiesto.

Documentazione Django

Deprecato dalla versione 1.9: on_delete diventerà un argomento obbligatorio in Django 2.0. Nelle versioni precedenti il ​​valore predefinito è CASCADE.


11

Da Django 2.0 on_deleteè richiesto:

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

Eliminerà i dati della tabella figlio se l'utente viene eliminato. Per maggiori dettagli controlla la documentazione di Django.


1
Perché questa risposta mentre Andrey ha risposto prima con queste informazioni?
Samuel Dauzon

11

Dal momento che Django 2.0 il campo ForeignKey richiede due argomenti posizionali:

  1. il modello su cui mappare
  2. l'argomento on_delete
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Ecco alcuni metodi che possono essere utilizzati in on_delete

  1. CASCATA

Elimina in cascata. Django emula il comportamento del vincolo SQL ON DELETE CASCADE ed elimina anche l'oggetto contenente la ForeignKey

  1. PROTEGGERE

Impedisci l'eliminazione dell'oggetto a cui fa riferimento sollevando ProtectedError, una sottoclasse di django.db.IntegrityError.

  1. FARE NIENTE

Nessuna azione. Se il back-end del database applica l'integrità referenziale, ciò causerà un IntegrityError a meno che non si aggiunga manualmente un vincolo SQL ON DELETE al campo del database.

puoi trovare di più su on_delete leggendo la documentazione .


4

Se stai usando foreignkey allora devi usare "on_delete = models.CASCADE" in quanto eliminerà la complessità sviluppata dopo aver cancellato l'elemento originale dalla tabella genitore. Così semplice.

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

3

Ecco le opzioni disponibili se aiuta qualcuno per on_delete

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL


1

Dopo la versione 1.9 di Django, on_deletedivenne un argomento obbligatorio, cioè da Django 2.0.

Nelle versioni precedenti, il valore predefinito è CASCADE.

Quindi, se vuoi replicare la funzionalità che hai usato nelle versioni precedenti. Usa il seguente argomento.

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

Ciò avrà lo stesso effetto delle versioni precedenti , senza specificarlo esplicitamente.

Documentazione ufficiale su altri argomenti che vanno con on_delete


0

Se non sai quale opzione inserire nel file params. Voglio solo mantenere il valore predefinito come on_delete=Noneprima della migrazione:

on_delete = models.CASCADE

Questo è uno snippet di codice nella vecchia versione:

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

Si è verificato un problema simile che è stato risolto aggiungendo entrambi questi due parametri a ForeignKey: null = True, on_delete = models.SET_NULL


-3

Questo ha funzionato per me pip install django-csvimport --upgrade


2
Come risponde questo alla domanda?
cezar

Ciao Mayank. Probabilmente hai fatto qualcos'altro per correggere l'errore o stai utilizzando una versione precedente di django.
Chris Dare

Questo problema viene risolto fornendo un valore per l'argomento "on_delete" a models.ForeignKey
Chris Dare

Stai usando Django prima della versione 2. Perché tutte le versioni successive hanno fatto on_deleteuna compulsione! Per impostazione predefinita nelle versioni precedenti, eraon_delete = models.CASCADE
Optider
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.