Mendapatkan TypeError: __init __ () kehilangan 1 argumen posisi yang diperlukan: 'on_delete' saat mencoba menambahkan tabel induk setelah tabel anak dengan entri

92

Saya memiliki dua kelas dalam database sqlite saya, tabel induk bernama Categoriedan tabel anak disebut Article. Saya membuat kelas tabel anak pertama dan menambahkan entri. Jadi pertama saya punya ini:

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

Dan setelah saya menambahkan tabel induk, dan sekarang models.pytampilan saya seperti ini:

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

Jadi ketika saya lari python manage.py makemigrations <my_app_name>, saya mendapatkan kesalahan ini:

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'

Saya telah melihat beberapa masalah serupa di stackoverflow, tetapi tampaknya bukan masalah yang sama: __init __ () kehilangan 1 argumen posisi yang diperlukan: 'kuantitas'

Christian Lisangola
sumber
3
versi django manakah yang anda gunakan?
alfonso.kim
2
Jadi bingung apa disini? Seperti yang dikatakan dengan jelas oleh kesalahan, ForeignKey memiliki argumen yang diperlukan on_delete,. Lihat dokumennya .
Daniel Roseman
Saya tidak membutuhkan on_deleteparameter, apakah itu wajib?
Christian Lisangola
@ jochri3 Ya, diperlukan argumen posisi berarti itu wajib. Periksa dokumentasi untuk mengetahui opsi mana yang paling sesuai dengan kebutuhan Anda.
cezar

Jawaban:

168

Anda dapat mengubah properti categoriekelas Articleseperti ini:

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

dan kesalahan akan hilang.

Akhirnya Anda mungkin memerlukan opsi lain untuk on_delete, periksa dokumentasi untuk lebih jelasnya:

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

EDIT:

Seperti yang Anda nyatakan dalam komentar Anda, bahwa Anda tidak memiliki persyaratan khusus untuk itu on_delete, Anda dapat menggunakan opsi DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...
cezar
sumber
1
on_delete = models.CASCADE adalah default di Django <2
Peter F
46

Sejak Django 2.x, on_deletediperlukan.

Dokumentasi Django

Tidak digunakan lagi sejak versi 1.9: on_delete akan menjadi argumen yang dibutuhkan dalam Django 2.0. Dalam versi yang lebih lama, defaultnya adalah CASCADE.

Andrey Zhilyakov
sumber
11

Dari Django 2.0 on_deletediperlukan:

pengguna = model.OneToOneField (Pengguna, on_delete = models.CASCADE)

Ini akan menghapus data tabel anak jika Pengguna dihapus. Untuk lebih detil periksa dokumentasi Django.

Javed Gouri
sumber
1
Mengapa jawaban ini sementara Andrey menanggapi sebelumnya dengan informasi ini?
Samuel Dauzon
11

Sejak Django 2.0 bidang ForeignKey membutuhkan dua argumen posisi:

  1. model yang akan dipetakan
  2. argumen on_delete
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

Berikut beberapa metode yang bisa digunakan di on_delete

  1. RIAM

Penghapusan bertingkat. Django mengemulasi kelakuan batasan SQL ON DELETE CASCADE dan juga menghapus objek yang mengandung ForeignKey.

  1. MELINDUNGI

Cegah penghapusan objek yang direferensikan dengan memunculkan ProtectedError, subkelas dari django.db.IntegrityError.

  1. TIDAK MELAKUKAN APAPUN

Jangan bertindak. Jika backend database Anda menerapkan integritas referensial, ini akan menyebabkan IntegrityError kecuali Anda menambahkan batasan SQL ON DELETE secara manual ke kolom database.

Anda dapat menemukan lebih banyak tentang on_delete dengan membaca dokumentasi .

Thusitha Deepal
sumber
4

Jika Anda menggunakan foreignkey maka Anda harus menggunakan "on_delete = models.CASCADE" karena ini akan menghilangkan kerumitan yang dikembangkan setelah menghapus elemen asli dari tabel induk. Sesimpel itu.

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

Berikut adalah opsi yang tersedia jika membantu siapa pun untuk on_delete

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL

Tarun Behal
sumber
1

Pasang Django versi 1.9, on_deletemenjadi argumen yang dibutuhkan, yaitu dari Django 2.0.

Pada versi lama, defaultnya adalah CASCADE.

Jadi, jika Anda ingin mereplikasi fungsionalitas yang Anda gunakan di versi sebelumnya. Gunakan argumen berikut.

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

Ini akan memiliki efek yang sama seperti pada versi sebelumnya , tanpa menentukannya secara eksplisit.

Dokumentasi Resmi tentang argumen lain yang menyertai on_delete

Optider
sumber
0

Jika Anda tidak tahu opsi mana untuk memasukkan params. Hanya ingin mempertahankan nilai default seperti on_delete=Nonesebelum migrasi:

on_delete = models.CASCADE

Ini adalah cuplikan kode di versi lama:

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

Memiliki masalah serupa yang diselesaikan dengan menambahkan kedua parameter ini ke ForeignKey: null = True, on_delete = models.SET_NULL

Nir Tsabar
sumber
-3

Ini berhasil untuk saya pip install django-csvimport --upgrade

Mayank Jaiswal
sumber
2
Bagaimana ini menjawab pertanyaan?
cezar
Hai Mayank. Anda mungkin melakukan sesuatu yang lain untuk memperbaiki kesalahan itu atau Anda menggunakan versi django sebelumnya.
Chris Dare
Ini diselesaikan dengan memberikan nilai untuk argumen "on_delete" ke model. ForignKey
Chris Dare
Anda menggunakan Django sebelum versi 2. Karena semua terbitan yang lebih baru telah membuat on_deletesuatu keharusan! Secara default di versi sebelumnya, ituon_delete = models.CASCADE
Optider