Написание функции __init__, которая будет использоваться в модели django

Я пытаюсь написать функцию __init__ для одной из моих моделей, чтобы я мог создать объект, выполнив:

p = User('name','email')

Когда я пишу модель, у меня есть:

def __init__(self, name, email, house_id, password):
    models.Model.__init__(self)
    self.name = name
    self.email = email

Это работает, и я могу сохранить объект в базе данных, но когда я выполняю User.objects.all(), он ничего не вытаскивает, если я не User.objects.all() свою функцию __init__. Есть идеи?

Ответ 1

Полагаясь на встроенную функциональность Django и передавая именованные параметры, это самый простой способ.

p = User(name="Fred", email="[email protected]")

Но если вы настроились на сохранение нескольких нажатий клавиш, я бы предложил добавить статический метод удобства в класс вместо того, чтобы возиться с инициализатором.

# In User class declaration
@classmethod
def create(cls, name, email):
  return cls(name=name, email=email)

# Use it
p = User.create("Fred", "[email protected]")

Ответ 2

Django ожидает, что сигнатура конструктора модели будет (self, *args, **kwargs) или некоторая разумная факсимиле. Ваше изменение подписи на нечто совершенно несовместимое нарушило его.

Ответ 3

Правильный ответ заключается в том, чтобы избежать переопределения __init__ и написать класс, как описано в документах Django.

Но это можно сделать так, как вы пытаетесь, вам просто нужно добавить *args, **kwargs, чтобы принять ваш __init__, и передать их на вызов метода super.

def __init__(self, name, email, house_id, password, *args, **kwargs):
        super(models.Model, self).__init__(self, *args, **kwargs)
        self.name = name
        self.email = email

Ответ 4

Не создавайте модели с параметрами args. Если вы сделаете такую ​​модель:

 User('name','email')

Он становится очень нечитаемым очень быстро, поскольку большинство моделей требуют больше, чем для инициализации. Вы могли бы легко в итоге:

User('Bert', 'Reynolds', '[email protected]','0123456789','5432106789',....)

Другая проблема заключается в том, что вы не знаете, является ли "Bert" первой или последней. Последние два номера могут быть просто номером телефона и идентификатором системы. Но без его явного вы будете легче смешивать их или смешивать заказ, если используете идентификаторы. Более того, что делает это на основе заказа, будет еще одно ограничение для других разработчиков, которые используют этот метод и не будут помнить произвольный порядок параметров.

Вместо этого вы должны предпочесть что-то вроде этого:

User(
    first_name='Bert',
    last_name='Reynolds',
    email='[email protected]',
    phone='0123456789',
    system_id='5432106789',
)

Если это для тестов или что-то в этом роде, вы можете использовать factory для быстрого создания моделей. Ссылка на ссылку factory может быть полезна: http://factoryboy.readthedocs.org/en/latest/