Obteniendo TypeError: __init __ () falta 1 argumento posicional requerido: 'on_delete' al intentar agregar la tabla principal después de la tabla secundaria con entradas

92

Tengo dos clases en mi base de datos sqlite, una tabla principal llamada Categoriey la tabla secundaria llamada Article. Primero creé la clase de tabla secundaria y agregué entradas. Así que primero tuve esto:

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

Y después de haber agregado la tabla principal, y ahora mi models.pyaspecto es así:

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

Entonces, cuando corro python manage.py makemigrations <my_app_name>, aparece este error:

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'

He visto algunos problemas similares en stackoverflow, pero parece que no es el mismo problema: __init __ () falta 1 argumento posicional requerido: 'cantidad'

Christian Lisangola
fuente
3
¿Qué versión de django estás usando?
alfonso.kim
2
Entonces, ¿de qué estás confundido aquí? Como dice claramente el error, ForeignKey tiene un argumento necesario, on_delete. Consulte los documentos .
Daniel Roseman
No necesito el on_deleteparámetro, ¿es obligatorio?
Christian Lisangola
@ jochri3 Sí, el argumento posicional requerido significa que es obligatorio. Consulte la documentación para averiguar qué opción se adapta mejor a sus necesidades.
cezar

Respuestas:

168

Puede cambiar la propiedad categoriede la clase de Articleesta manera:

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

y el error debería desaparecer.

Eventualmente, es posible que necesite otra opción para on_delete, consulte la documentación para obtener más detalles:

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

EDITAR:

Como indicó en su comentario, para el que no tiene requisitos especiales on_delete, puede usar la opción DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...
cezar
fuente
1
on_delete = modelos.CASCADE es el predeterminado en Django <2
Peter F
46

Desde Django 2.x, on_deletese requiere.

Documentación de Django

En desuso desde la versión 1.9: on_delete se convertirá en un argumento obligatorio en Django 2.0. En versiones anteriores, el valor predeterminado es CASCADE.

Andrey Zhilyakov
fuente
11

De Django 2.0 on_deletese requiere:

usuario = modelos.OneToOneField (Usuario, on_delete = modelos.CASCADE)

Eliminará los datos de la tabla secundaria si se elimina el usuario. Para obtener más detalles, consulte la documentación de Django.

Javed Gouri
fuente
1
¿Por qué esta respuesta mientras que Andrey respondió antes con esta información?
Samuel Dauzon
11

Desde Django 2.0, el campo ForeignKey requiere dos argumentos posicionales:

  1. el modelo para mapear
  2. el argumento on_delete
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Aquí hay algunos métodos que se pueden usar en on_delete

  1. CASCADA

Cascade elimina. Django emula el comportamiento de la restricción SQL ON DELETE CASCADE y también elimina el objeto que contiene ForeignKey

  1. PROTEGER

Evite la eliminación del objeto referenciado generando ProtectedError, una subclase de django.db.IntegrityError.

  1. HACER NADA

No tomar ninguna medida. Si el backend de su base de datos impone la integridad referencial, esto causará un IntegrityError a menos que agregue manualmente una restricción de SQL ON DELETE al campo de la base de datos.

puede encontrar más sobre on_delete leyendo la documentación .

Thusitha Deepal
fuente
4

Si está usando una clave externa, entonces debe usar "on_delete = models.CASCADE" ya que eliminará la complejidad desarrollada después de eliminar el elemento original de la tabla principal. Tan sencillo como eso.

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

Aquí hay opciones disponibles si ayuda a alguien para on_delete

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL

Tarun Behal
fuente
1

La versión 1.9 de Post Django se on_deleteconvirtió en un argumento obligatorio, es decir, de Django 2.0.

En versiones anteriores, por defecto es CASCADE.

Entonces, si desea replicar la funcionalidad que utilizó en versiones anteriores. Utilice el siguiente argumento.

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

Esto tendrá el mismo efecto que en versiones anteriores , sin especificarlo explícitamente.

Documentación oficial sobre otros argumentos que acompañan a on_delete

Optider
fuente
0

Si no sabe qué opción ingresar a los parámetros. Solo quiero mantener el valor predeterminado como on_delete=Noneantes de la migración:

on_delete = modelos.CASCADE

Este es un fragmento de código en la versión anterior:

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
fuente
0

Tuve un problema similar que se resolvió agregando estos dos parámetros a ForeignKey: null = True, on_delete = models.SET_NULL

Nir Tsabar
fuente
-3

Esto funcionó para mi pip install django-csvimport --upgrade

Mayank Jaiswal
fuente
2
¿Cómo responde esto a la pregunta?
cezar
Hola Mayank. Probablemente hizo algo más para corregir ese error o está usando una versión anterior de django.
Chris Dare
Esto se resuelve proporcionando un valor para el argumento "on_delete" a los modelos
Chris Dare
Estás usando Django antes de la versión 2. ¡Porque todas las versiones posteriores han hecho on_deleteuna obligación! De forma predeterminada en versiones anteriores, lo eraon_delete = models.CASCADE
Optider