TypeError alınıyor: __init __ () 1 gerekli konumsal bağımsız değişken eksik: 'on_delete' girişli alt tablodan sonra üst tablo eklemeye çalışırken


92

Sqlite veritabanımda iki sınıfım var, adlı bir üst tablo Categorieve adlı alt tablo Article. Önce alt tablo sınıfını oluşturdum ve girişler ekledim. İlk önce şunu aldım:

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

Üst tabloyu ekledikten sonra ve şimdi models.pyşuna benziyor:

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

Bu yüzden çalıştırdığımda python manage.py makemigrations <my_app_name>şu hatayı alıyorum:

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'da bazı benzer sorunlar gördüm, ancak aynı sorun görünmüyor: __init __ () 1 gerekli konumsal argüman eksik: 'miktar'


3
hangi django sürümünü kullanıyorsunuz?
alfonso.kim

2
Peki burada kafanız ne karıştı? Hatanın açıkça ifade ettiği gibi, ForeignKey'in gerekli bir argümanı vardır on_delete. Dokümanlara bakın .
Daniel Roseman

on_deleteParametreye ihtiyacım yok , zorunlu mu?
Christian Lisangola

@ jochri3 Evet, gerekli konumsal argüman zorunlu olduğu anlamına gelir. İhtiyaçlarınıza en uygun seçeneğin hangisi olduğunu bulmak için belgelere bakın.
cezar

Yanıtlar:


168

categorieSınıfın özelliğini şu şekilde değiştirebilirsiniz Article:

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

ve hata ortadan kalkmalıdır.

Sonunda başka bir seçeneğe ihtiyacınız olabilir on_delete, daha fazla ayrıntı için belgelere bakın:

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

DÜZENLE:

Yorumunuzda belirttiğiniz gibi, herhangi bir özel gereksiniminiz olmadığı için on_deleteşu seçeneği kullanabilirsiniz DO_NOTHING:

# ...
on_delete=models.DO_NOTHING,
# ...

1
on_delete = models.CASCADE Django <2
Peter F

46

Django 2.x on_deletegerekli olduğundan.

Django Belgeleri

1.9 sürümünden beri kullanımdan kaldırıldı: on_delete, Django 2.0'da gerekli bir argüman haline gelecek. Eski sürümlerde varsayılan olarak CASCADE'dir.


11

Django 2.0'dan on_deletegereklidir:

user = models.OneToOneField (Kullanıcı, on_delete = modeller.CASCADE)

Kullanıcı silinirse alt tablo verilerini siler. Daha fazla ayrıntı için Django belgelerine bakın.


1
Andrey bu bilgiyle daha önce yanıt verirken neden bu cevap?
Samuel Dauzon

11

Django 2.0'dan beri ForeignKey alanı iki konumsal argüman gerektirir:

  1. eşlenecek model
  2. on_delete argümanı
categorie = models.ForeignKey('Categorie', on_delete=models.PROTECT)

İşte on_delete'de kullanılabilecek bazı yöntemler

  1. ÇAĞLAYAN

Basamakla siler. Django, DELETE CASCADE ÜZERİNDEKİ SQL kısıtlamasının davranışını taklit eder ve ayrıca ForeignKey içeren nesneyi siler.

  1. KORUYUN

Django.db.IntegrityError'ın bir alt sınıfı olan ProtectedError'ı yükselterek başvurulan nesnenin silinmesini önleyin.

  1. HİÇBİR ŞEY YAPMA

Eylemsiz kal. Veritabanı arka ucunuz bilgi tutarlılığını zorlarsa, veritabanı alanına manuel olarak bir SQL ON DELETE kısıtlaması eklemediğiniz sürece bu bir IntegrityError hatasına neden olur.

belgeleri okuyarak on_delete hakkında daha fazla bilgi edinebilirsiniz .


4

Foreignkey kullanıyorsanız, "on_delete = models.CASCADE" kullanmanız gerekir çünkü bu, orijinal öğeyi ana tablodan sildikten sonra oluşan karmaşıklığı ortadan kaldıracaktır. Kadar basit.

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

3

On_delete için herhangi birine yardımcı oluyorsa mevcut seçenekler burada

CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL


1

Post Django sürüm 1.9, on_deletegerekli bir argüman oldu, yani Django 2.0'dan.

Eski sürümlerde varsayılan olarak CASCADE'dir.

Öyleyse, önceki sürümlerde kullandığınız işlevselliği çoğaltmak istiyorsanız. Aşağıdaki argümanı kullanın.

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

Bu, açıkça belirtilmeden önceki sürümlerde olduğu gibi aynı etkiye sahip olacaktır .

On_delete ile birlikte gelen diğer argümanlara ilişkin Resmi Belgeler


0

Parametreleri hangi seçeneği gireceğinizi bilmiyorsanız. Taşıma işleminden önceki gibi varsayılan değeri korumak istiyorum on_delete=None:

on_delete = modeller.CASCADE

Bu, eski sürümdeki bir kod parçacığıdır:

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

Bu iki parametrenin de ForeignKey'e eklenmesiyle çözülen benzer bir sorun vardı: null = True, on_delete = models.SET_NULL


-3

Bu benim için çalıştı pip install django-csvimport --upgrade


2
Bu soruya nasıl cevap veriyor?
cezar

Merhaba Mayank. Muhtemelen bu hatayı düzeltmek için başka bir şey yaptınız veya django'nun önceki bir sürümünü kullanıyorsunuz.
Chris Dare

Bu, modellere "on_delete" argümanı için bir değer sağlanarak çözülür.ForeignKey
Chris Dare

Django'yu sürüm 2'den önce kullanıyorsunuz. Çünkü sonraki tüm sürümler on_deletebir zorunluluk haline getirdi ! Önceki sürümlerde varsayılan olarak şöyleydion_delete = models.CASCADE
Optider
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.