Какие данные я передаю в метод Django Model.save ()? - PullRequest
1 голос
/ 01 июня 2010

Допустим, мы получаем POSTed форму, подобную этой, в Django:

rate=10
items= [23,12,31,52,83,34]

Предметы являются первичными ключами модели Предмета.У меня есть куча бизнес-логики, которая будет запускать и создавать больше элементов на основе этих данных, результатов некоторых поисков БД и некоторой бизнес-логики.Я хочу поместить эту логику в сигнал сохранения или переопределенный метод Model.save() другой модели (назовем его Inventory).Бизнес-логика будет работать, когда я создаю новый объект Inventory, используя эти данные формы.Инвентарь будет выглядеть так:

class Inventory(models.Model):
    picked_items = models.ManyToManyField(Item, related_name="items_picked_set")
    calculated_items = models.ManyToManyField(Item, related_name="items_calculated_set")
    rate = models.DecimalField()
    ... other fields here ... 

Новый calculated_items будет создан на основе переданных элементов, которые будут сохранены как picked_items.

Мой вопрос таков:лучше для метода save() в этой модели принять:

  • объект запроса (мне не очень нравится эта связь)
  • данные формы в качестве аргументов или kwargs (aсписок первичных ключей и другие поля формы)
  • список элементов (форма или представление вызывающей стороны выполнит поиск списка элементов и создаст список, а также передаст другие поля формы)
  • какой-то другой подход?

Я знаю, что это немного субъективно, но мне было интересно, какова общая идея.Я просмотрел много кода, но мне трудно найти шаблон, который мне нравится.

Уточнение:

ОК, так что согласие заключается в том, чтоон должен войти в другую функцию модели, что-то вроде inventory.calculate(...), которая затем будет создавать все, выполнять бизнес-логику и т. д. Это хорошо знать.Мой вопрос остается: где лучше всего искать данные формы в объектах БД?Должен ли вызывающий этой функции преобразовывать первичные ключи в модели базы данных или методы модели принимают первичные ключи и делают это сами?Это то, что я хочу сделать таким же образом для всего проекта.

Пояснение 2:

ОК, так что теперь есть некоторые разногласия по поводу того, что переопределение saveНормально или нет.

Когда вы получаете отправку формы для простой операции типа CRUD, вы передаете модели и значения в качестве аргументов Model.objects.create(...) или переопределяете save или используете сигналы или что-то еще.

Я думаю, что суть моего вопроса заключается в следующем:

Если отправка формы имеет связанные модели, используемые для бизнес-логики, то вам нужно записать некоторую бизнес-логику в слой модели.Когда вы делаете это, куда он должен идти и должен ли этот метод принимать список объектов или список идентификаторов?Должны ли API модели принимать объекты или идентификаторы?

1 Ответ

1 голос
/ 04 июня 2010

ОК, поэтому первые два ответа, которые я получил, теперь противоречат другим. Я исследовал это, и я собираюсь предпринять попытку ответить на него сам. Пожалуйста, проголосуйте, если считаете, что это правильно, и / или прокомментируйте, если вы не согласны с моими доводами.

  • Методы в моделях должны принимать объекты и списки объектов, а не идентификаторы как int / long или списки идентификаторов или что-то в этом роде. Это потому, что он, вероятно, будет вызываться из представления или формы, и они имеют доступ к полным объектам из cleaned_data dict. Метод create() в классах менеджера является еще одним примером, в котором сам django принимает объекты.

  • Вызывающий методы уровня модели должен искать и преобразовывать идентификаторы в полные объекты.

  • Вы можете переопределить save(), но если вы это сделаете, вы должны быть осторожны, чтобы принять args и **kwargs

  • Если модели охватывают области применения, вы должны учитывать сигналы вместо переопределения save

  • Не пытайтесь получить умный переопределение метода менеджера моделей create. Он не будет вызван, если слой представления создаст новый объект и сохранит его. Если вам нужно выполнить дополнительную обработку перед сохранением, вы можете переопределить save или __init__ или перехватить сигнал. если вы переопределите __init__, вы можете проверить наличие pk, чтобы определить, существует ли он в БД или нет.

Сейчас я собираюсь поместить свой код создания в отдельный метод, пока не выясню, какой из методов мне больше нравится.

Я думаю, что это хороший набор рекомендаций для добавления методов в слой модели. Что-то, что я пропустил?

...