web-dev-qa-db-fra.com

Obtenir TypeError: __init __ () manquant 1 argument positionnel requis: 'on_delete' lors de la tentative d'ajout d'une table parent après une table enfant avec des entrées

J'ai deux classes dans ma base de données sqlite, une table parent nommée Categorie et la table enfant appelée Article. J'ai d'abord créé la classe de la table enfant et ajouté des entrées. Alors j'ai d'abord eu ceci:

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

Et après avoir ajouté la table parente, et maintenant mon models.py ressemble à ceci:

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

Alors quand je lance python manage.py makemigrations <my_app_name>, j'obtiens cette erreur:

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'

J'ai rencontré des problèmes similaires dans stackoverflow, mais il semble que ce ne soit pas le même problème: __ init __ () manquant 1 argument de position requis: 'quantité'

70

Vous pouvez changer la propriété categorie de la classe Article comme ceci:

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

et l'erreur devrait disparaître.

Éventuellement, vous aurez peut-être besoin d'une autre option pour on_delete. Consultez la documentation pour plus de détails:

https://docs.djangoproject.com/fr/1.11/ref/models/fields/#Django.db.models.ForeignKey

MODIFIER:

Comme vous l'avez indiqué dans votre commentaire, vous n'avez pas d'exigences particulières pour on_delete, vous pouvez utiliser l'option DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...
115
cezar

Depuis Django 2.x, on_delete est requis.

Documentation Django

Déconseillé depuis la version 1.9: on_delete deviendra un argument obligatoire dans Django 2.0. Dans les versions antérieures, CASCADE est utilisé par défaut.

33
Andrey Zhilyakov

Jusqu'au Django 1.9, un modèle ressemblerait à ceci:

from Django.db import models
class Article(models.Model):
    category = models.ForeignKey(Category)
    title =  models.CharField(max_length=55)
    # ...

    def __str__(self):
        return self.title

ForeignKey est un champ Django permettant de définir une relation plusieurs-à-un.

Jusqu'au Django 1.9, le champ ForeignKey ne nécessitait qu'un seul argument: le modèle à mapper.

Depuis Django 2.0 le champ ForeignKey ) nécessite deux arguments de position :

1- le modèle à mapper à

2-l'argument on_delete

Pour résoudre rapidement "l'argument positionnel manquant 1 requis: on_delete", mettez à jour le modèle:

from Django.db import models
class Article(models.Model):
    category = models.ForeignKey('Category', on_delete=models.PROTECT)
    title =  models.CharField(max_length=55)
    # ...

    def __str__(self):
        return self.title

Après avoir corrigé ForeignKey, vous pourrez exécuter les migrations sans problème:

python manage.py migrate

Merci à Valentino

10
Alex Jolig

De Django 2.0 on_delete est requis:

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

Il supprimera les données de la table enfant si l'utilisateur est supprimé. Pour plus de détails, consultez la documentation Django.

8
Javed Gouri

Si vous utilisez foreignkey, vous devez utiliser "on_delete = models.CASCADE" car cela éliminera la complexité créée après la suppression de l'élément d'origine de la table parente. Aussi simple que cela.

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

Depuis Django 2.0, le champ ForeignKey nécessite deux arguments de position:

  1. le modèle à mapper
  2. l'argument on_delete
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Voici quelques méthodes que l'on peut utiliser dans on_delete

  1. CASCADE

Suppression en cascade. Django émule le comportement de la contrainte SQL SUR DELETE CASCADE et supprime également l'objet contenant la ForeignKey

  1. PROTÉGER

Empêchez la suppression de l'objet référencé en élevant ProtectedError, une sous-classe de Django.db.IntegrityError.

  1. NE FAIS RIEN

Ne pas agir. Si votre base de données applique l'intégrité référentielle, cela provoquera une erreur IntegrityError sauf si vous ajoutez manuellement une contrainte SQL ON DELETE au champ de la base de données.

vous pouvez en savoir plus sur on_delete en lisant documentation .

4
Thusitha Deepal

Voici les options disponibles si ça aide quelqu'un pour on_delete

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL

3
Tarun Behal

Cela a fonctionné pour moi pip install Django-csvimport --upgrade

0
Mayank Jaiswal