Написание функции __init__ для использования в модели django - PullRequest
63 голосов
/ 09 мая 2009

Я пытаюсь написать функцию __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(), он ничего не вытягивает, пока я не отключу свою функцию __init__. Есть идеи?

Ответы [ 4 ]

96 голосов
/ 09 мая 2009

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

p = User(name="Fred", email="fred@example.com")

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

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

# Use it
p = User.create("Fred", "fred@example.com")
41 голосов
/ 09 мая 2009

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

15 голосов
/ 29 января 2015

Правильный ответ - избегать переопределения __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
2 голосов
/ 20 января 2015

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

 User('name','email')

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

User('Bert', 'Reynolds', 'me@bertreynolds.com','0123456789','5432106789',....)

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

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

User(
    first_name='Bert',
    last_name='Reynolds',
    email='me@bertreynolds.com',
    phone='0123456789',
    system_id='5432106789',
)

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

...