Получение TypeError: __init __ () отсутствует 1 обязательный позиционный аргумент: 'on_delete' при попытке добавить родительскую таблицу после дочерней таблицы с записями

92

У меня есть два класса в моей базе данных sqlite, родительская таблица с именем Categorieи дочерняя таблица с именем Article. Сначала я создал класс дочерней таблицы и добавил записи. Итак, сначала у меня было это:

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

И после того, как я добавил родительскую таблицу, теперь мой models.pyвид выглядит так:

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

Итак, когда я бегу python manage.py makemigrations <my_app_name>, я получаю эту ошибку:

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'

Я видел некоторые похожие проблемы в stackoverflow, но, похоже, это не та же проблема: __init __ () отсутствует 1 требуемый позиционный аргумент: 'количество'

Кристиан Лисангола
источник
3
какую версию django вы используете?
alfonso.kim
2
Так что вас здесь смущает? Как ясно сказано в ошибке, ForeignKey имеет обязательный аргумент on_delete. См. Документы .
Дэниел
on_deleteПараметр мне не нужен , он обязателен?
Кристиан Лисангола
@ jochri3 Да, обязательный позиционный аргумент означает, что он обязателен. Ознакомьтесь с документацией, чтобы узнать, какой вариант лучше всего соответствует вашим потребностям.
cezar

Ответы:

168

Вы можете изменить свойство categorieкласса Articleследующим образом:

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

и ошибка должна исчезнуть.

В конце концов вам может понадобиться другой вариант on_delete, подробности смотрите в документации:

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

РЕДАКТИРОВАТЬ:

Как вы заявили в своем комментарии, что у вас нет особых требований on_delete, вы можете использовать опцию DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...
цезарь
источник
1
on_delete = models.CASCADE по умолчанию в Django <2
Питер Ф,
46

Начиная с Django 2.x, on_deleteтребуется.

Документация Django

Не рекомендуется с версии 1.9: on_delete станет обязательным аргументом в Django 2.0. В более старых версиях по умолчанию используется КАСКАД.

Андрей Жиляков
источник
11

От Django 2.0 on_deleteтребуется:

user = models.OneToOneField (Пользователь, on_delete = models.CASCADE)

Он удалит данные дочерней таблицы, если пользователь будет удален. Для получения дополнительных сведений обратитесь к документации Django.

Джавед Гури
источник
1
Почему этот ответ, в то время как Андрей ранее отвечал с этой информацией?
Сэмюэл Дозон
11

Начиная с Django 2.0 для поля ForeignKey требуются два позиционных аргумента:

  1. модель для сопоставления
  2. аргумент on_delete
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Вот несколько методов, которые можно использовать в on_delete

  1. КАСКАД

Каскад удаляет. Django имитирует поведение ограничения SQL ON DELETE CASCADE, а также удаляет объект, содержащий ForeignKey.

  1. ЗАЩИТИТЬ

Предотвратите удаление указанного объекта, вызвав ProtectedError, подкласс django.db.IntegrityError.

  1. НИЧЕГО НЕ ДЕЛАТЬ

Не предпринимайте никаких действий. Если серверная часть вашей базы данных обеспечивает ссылочную целостность, это вызовет IntegrityError, если вы вручную не добавите ограничение SQL ON DELETE в поле базы данных.

вы можете узнать больше о on_delete, прочитав документацию .

Сусита Дипал
источник
4

Если вы используете foreignkey, вы должны использовать «on_delete = models.CASCADE», так как это устранит сложность, возникшую после удаления исходного элемента из родительской таблицы. Так просто, как, что.

categorie = models.ForeignKey('Categorie', on_delete=models.CASCADE)
Бала Кисве
источник
3

Вот доступные варианты, если это кому-то поможет для on_delete

КАСКАД, DO_NOTHING, ЗАЩИТА, УСТАНОВИТЬ, УСТАНОВИТЬ_ДЕФАУЛЬТ, УСТАНОВИТЬ

Тарун Бехал
источник
1

Опубликовать Django версии 1.9, on_deleteстало обязательным аргументом, т.е. из Django 2.0.

В более старых версиях по умолчанию используется КАСКАД.

Итак, если вы хотите воспроизвести функциональность, которую вы использовали в более ранних версиях. Используйте следующий аргумент.

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

Это будет иметь тот же эффект, что и в более ранних версиях , без его явного указания.

Официальная документация по другим аргументам, связанным с on_delete

Optider
источник
0

Если вы не знаете, какой вариант ввести в params. Просто хочу сохранить значение по умолчанию, как on_delete=Noneдо миграции:

on_delete = models.CASCADE

Это фрагмент кода из старой версии:

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
источник
0

Была аналогичная проблема, которая была решена путем добавления обоих этих двух параметров в ForeignKey: null = True, on_delete = models.SET_NULL

Нир Цабар
источник
-3

Это сработало для меня pip install django-csvimport --upgrade

Майанк Джайсвал
источник
2
Как это отвечает на вопрос?
cezar
Привет, Маянк. Вероятно, вы сделали что-то еще, чтобы исправить эту ошибку, или вы используете более раннюю версию django.
Крис Дэйр
Эта проблема решается путем передачи моделям значения аргумента on_delete. ForeignKey
Крис Дэр
Вы используете Django до версии 2. Потому что все более поздние выпуски носят on_deleteпринудительный характер! По умолчанию в более ранних версиях это былоon_delete = models.CASCADE
Optider