Pobieranie TypeError: __init __ () brakuje 1 wymaganego argumentu pozycyjnego: „on_delete” podczas próby dodania tabeli nadrzędnej po tabeli podrzędnej z wpisami

92

Mam dwie klasy w mojej bazie danych sqlite, tabelę nadrzędną o nazwie Categoriei tabelę podrzędną o nazwie Article. Najpierw utworzyłem podrzędną klasę tabeli i dodaję wpisy. Więc najpierw miałem to:

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

A po dodaniu tabeli nadrzędnej, a teraz mój models.pywygląd wygląda tak:

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

Więc kiedy uruchamiam python manage.py makemigrations <my_app_name>, pojawia się ten błąd:

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'

I've seen some similar issues in stackoverflow, but it seems to not be the same problem: __init__() missing 1 required positional argument: 'quantity'

Christian Lisangola
źródło
3
wich version of django are you using?
alfonso.kim
2
So what are you confused about here? As the error clearly says, ForeignKey has a required argument, on_delete. See the docs.
Daniel Roseman
I dont need the on_delete parameter,is it obligatory?
Christian Lisangola
@jochri3 Yes, required positional argument means it is obligatory. Check the documentation to find out which option would best fit your needs.
cezar

Odpowiedzi:

168

You can change the property categorie of the class Article like this:

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

and the error should disappear.

Eventually you might need another option for on_delete, check the documentation for more details:

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

EDIT:

As you stated in your comment, that you don't have any special requirements for on_delete, you could use the option DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...
cezar
źródło
1
on_delete=models.CASCADE is the default in Django < 2
Peter F
46

Since Django 2.x, on_delete is required.

Django Documentation

Deprecated since version 1.9: on_delete will become a required argument in Django 2.0. In older versions it defaults to CASCADE.

Andrey Zhilyakov
źródło
11

From Django 2.0 on_delete is required:

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

It will delete the child table data if the User is deleted. For more details check the Django documentation.

Javed Gouri
źródło
1
Why this answer while Andrey response earlier with this information ?
Samuel Dauzon
11

Since Django 2.0 the ForeignKey field requires two positional arguments:

  1. the model to map to
  2. the on_delete argument
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Here are some methods can used in on_delete

  1. CASCADE

Cascade deletes. Django emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey

  1. PROTECT

Prevent deletion of the referenced object by raising ProtectedError, a subclass of django.db.IntegrityError.

  1. DO_NOTHING

Take no action. If your database backend enforces referential integrity, this will cause an IntegrityError unless you manually add an SQL ON DELETE constraint to the database field.

you can find more about on_delete by reading the documentation.

Thusitha Deepal
źródło
4

If you are using foreignkey then you have to use "on_delete=models.CASCADE" as it will eliminate the complexity developed after deleting the original element from the parent table. As simple as that.

categorie = models.ForeignKey('Categorie', on_delete=models.CASCADE)
Bala Kiswe
źródło
3

Here are available options if it helps anyone for on_delete

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL

Tarun Behal
źródło
1

Post Django version 1.9, on_delete became a required argument, i.e. from Django 2.0.

In older versions, it defaults to CASCADE.

So, if you want to replicate the functionality that you used in earlier versions. Use the following argument.

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

This will have the same effect as that was in earlier versions, without specifying it explicitly.

Official Documentation on other arguments that go with on_delete

Optider
źródło
0

If you don't know which option to enter the params. Just want to keep the default value like on_delete=None before migration:

on_delete=models.CASCADE

This is a code snippet in the old version:

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
źródło
0

Had a similar problem that resolved by adding both these two parameters to ForeignKey: null=True, on_delete=models.SET_NULL

Nir Tsabar
źródło
-3

This worked for me pip install django-csvimport --upgrade

Mayank Jaiswal
źródło
2
How does this answer the question?
cezar
Hi Mayank. You probably did something else to fix that error or you're using an earlier version of django.
Chris Dare
This is solved by supplying a value for the "on_delete" argument to models.ForeignKey
Chris Dare
You are using Django prior to version 2. Because all later releases have made on_delete a compulsion! By default in earlier versions, it was on_delete = models.CASCADE
Optider