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é'
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,
# ...
Depuis Django 2.x, on_delete
est requis.
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.
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
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.
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)
Depuis Django 2.0, le champ ForeignKey nécessite deux arguments de position:
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)
Voici quelques méthodes que l'on peut utiliser dans on_delete
Suppression en cascade. Django émule le comportement de la contrainte SQL SUR DELETE CASCADE et supprime également l'objet contenant la ForeignKey
Empêchez la suppression de l'objet référencé en élevant ProtectedError, une sous-classe de Django.db.IntegrityError.
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 .
Voici les options disponibles si ça aide quelqu'un pour on_delete
CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL
Cela a fonctionné pour moi pip install Django-csvimport --upgrade