การรับ 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 อาร์กิวเมนต์ตำแหน่งที่ต้องการ: 'quantity'


3
คุณใช้ django เวอร์ชั่นไหนอยู่
alfonso.kim

2
แล้วคุณจะสับสนอะไรที่นี่? ในฐานะที่เป็นข้อผิดพลาดอย่างชัดเจนกล่าวว่า ForeignKey on_deleteมีอาร์กิวเมนต์ที่จำเป็น ดูเอกสาร
Daniel Roseman

ฉันไม่ต้องการon_deleteพารามิเตอร์จำเป็นหรือไม่?
Christian Lisangola

@ 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
Peter F

46

เนื่องจาก Django 2.x on_deleteจำเป็นต้องมี

เอกสาร Django

เลิกใช้งานตั้งแต่เวอร์ชัน 1.9: on_delete จะกลายเป็นอาร์กิวเมนต์ที่จำเป็นใน Django 2.0 ในเวอร์ชันเก่าจะมีค่าเริ่มต้นเป็น CASCADE


11

จาก Django 2.0 on_deleteเป็นสิ่งจำเป็น:

ผู้ใช้ = models.OneToOneField (ผู้ใช้ on_delete = models.CASCADE)

จะลบข้อมูลตารางลูกหากผู้ใช้ถูกลบ สำหรับรายละเอียดเพิ่มเติมตรวจสอบเอกสาร Django


1
ทำไมคำตอบนี้ในขณะที่ Andrey ตอบกลับก่อนหน้านี้ด้วยข้อมูลนี้?
Samuel Dauzon

11

เนื่องจาก Django 2.0 ฟิลด์ ForeignKey ต้องการอาร์กิวเมนต์สองตำแหน่ง:

  1. โมเดลที่จะแมป
  2. on_delete อาร์กิวเมนต์
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

ต่อไปนี้เป็นวิธีการบางอย่างที่สามารถใช้ได้ใน on_delete

  1. น้ำตก

Cascade ลบ 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

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL


1

โพสต์ Django เวอร์ชัน 1.9 on_deleteกลายเป็นอาร์กิวเมนต์ที่จำเป็นเช่นจาก Django 2.0

ในเวอร์ชันเก่าจะมีค่าเริ่มต้นเป็น CASCADE

ดังนั้นหากคุณต้องการจำลองฟังก์ชันที่คุณใช้ในเวอร์ชันก่อนหน้านี้ ใช้อาร์กิวเมนต์ต่อไปนี้

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

สิ่งนี้จะมีผลเช่นเดียวกับในเวอร์ชันก่อนหน้าโดยไม่ต้องระบุอย่างชัดเจน

เอกสารอย่างเป็นทางการเกี่ยวกับข้อโต้แย้งอื่น ๆ ที่มาพร้อมกับ on_delete


0

หากคุณไม่ทราบว่าจะป้อนพารามิเตอร์ใด เพียงแค่ต้องการให้ค่าเริ่มต้นเหมือน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

0

มีปัญหาที่คล้ายกันซึ่งแก้ไขได้โดยการเพิ่มพารามิเตอร์ทั้งสองนี้ใน ForeignKey: null = True, on_delete = models.SET_NULL


-3

สิ่งนี้ได้ผลสำหรับฉัน pip install django-csvimport --upgrade


2
สิ่งนี้ตอบคำถามได้อย่างไร?
cezar

สวัสดี Mayank คุณอาจทำอย่างอื่นเพื่อแก้ไขข้อผิดพลาดนั้นหรือคุณกำลังใช้ django เวอร์ชันก่อนหน้า
Chris Dare

ซึ่งแก้ไขได้โดยการระบุค่าสำหรับอาร์กิวเมนต์ "on_delete" ให้กับโมเดลต่างประเทศ
Chris Dare

คุณกำลังใช้ Django ก่อนเวอร์ชัน 2 เนื่องจากการเผยแพร่ในภายหลังทั้งหมดทำให้เกิดon_deleteการบังคับ! โดยค่าเริ่มต้นในเวอร์ชันก่อนหน้าคือon_delete = models.CASCADE
Optider
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.