Страницы

Поиск по вопросам

воскресенье, 8 марта 2020 г.

TypeError: __init__() takes 2 positional arguments but 3 were given в Django

#python #django #django_orm


Есть вот такая система моделей

class NormalTag(models.Model):
    caption = models.CharField(max_length=1024, unique=True,
                                blank=False, default=None)
    def __init__(self, caption):
        super().__init__()
        self.caption = caption

    def __str__(self):
        return self.caption

class Tag(models.Model):
    caption = models.CharField(max_length=1024)

    def __init__(self, caption):
        super().__init__()
        self.caption = caption
        self.set_normaltag()

    def normalize(self):
        return self.caption.lower().replace(" ",'').replace("\"",'')

    def set_normaltag(self):
        try:
            normaltag = self.get_normaltag()
        except NormalTag.DoesNotExist:
            normaltag = NormalTag(self.normalize())
            normaltag.save()

    def get_normaltag(self):
        return NormalTag.objects.get(caption=self.normalize())

    def __str__(self):
        return self.caption


При вызове из шелла выдает ошибку:

[env]user ~/path/to/project > python manage.py shell
Python 3.5.2 (default, Jul  5 2016, 12:43:10) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from home.models import NormalTag, Tag
>>> t = Tag("ПроВеРка ТэГа")
Traceback (most recent call last):
  File "", line 1, in 
  File "/home/path/to/project/home/models.py", line 28, in __init__
    self.set_normaltag()
  File "/home/path/to/project/home/models.py", line 35, in set_normaltag
    normaltag = self.get_normaltag()
  File "/home/path/to/project/home/models.py", line 41, in get_normaltag
    return NormalTag.objects.get(caption=self.normalize())
  File "/home/path/to/env/lib/python3.5/site-packages/django/db/models/manager.py",
line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/path/to/env/lib/python3.5/site-packages/django/db/models/query.py",
line 379, in get
    num = len(clone)
  File "/home/path/to/env/lib/python3.5/site-packages/django/db/models/query.py",
line 238, in __len__
    self._fetch_all()
  File "/home/path/to/env/lib/python3.5/site-packages/django/db/models/query.py",
line 1087, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/home/path/to/env/lib/python3.5/site-packages/django/db/models/query.py",
line 66, in __iter__
    obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
  File "/home/path/to/env/lib/python3.5/site-packages/django/db/models/base.py",
line 565, in from_db
    new = cls(*values)
TypeError: __init__() takes 2 positional arguments but 3 were given


Так и не понял, откуда она берется.
    


Ответы

Ответ 1



В джанге много чего происходит магическим образом. То есть во фреймворке не всё соотвествует питону, хотя и написано на нём. В данном случае вы передали позиционный аргумент в модель, а при создании моделей нужно передавать только именованные аргументы. В вашем случае нужно было написать: t = Tag(caption="ПроВеРка ТэГа") И да, в моделях переопределять метод __init__ надо с осторожностью, если нужно добавить какие-то дополнительные действия во время создания модели, то лучше использовать метод менеджера модели create(), он создан специально для этого.

Ответ 2



У моделей есть перегруженный метод create() для создания объектов. Не стоит пользоваться конструктором. https://docs.djangoproject.com/en/1.10/ref/models/instances/ - пример сразу тут.

Комментариев нет:

Отправить комментарий