2016-01-15 2 views
0

У меня есть модель с методом настроены сохранить(), что создает промежуточные модели при соответствии условиям:.Переопределена сохранить() поведение метод не используется супер() сохранить() метод

class Person(models.Model): 
    integervalue = models.PositiveIntegerField(...) 
    some_field = models.CharField(...) 
    related_objects = models.ManyToManyField('OtherModel', through='IntermediaryModel') 
    ... 
    def save(self, *args, **kwargs): 
     if self.pk is None: # if a new object is being created - then 
      super(Person, self).save(*args, **kwargs) # save instance first to obtain PK for later 
      if self.some_field == 'Foo': 
       for otherModelInstance in OtherModel.objects.all(): # creates instances of intermediate model objects for all OtherModels 
        new_Intermediary_Model_instance = IntermediaryModel.objects.create(person = self, other = otherModelInstance) 
     super(Person, self).save(*args, **kwargs) #should be called upon exiting the cycle 

Однако, если для редактирования существующий Лицо как через оболочку, так и через интерфейс администратора - если я изменяю integeralue некоторого существующего Person - изменения не сохраняются. Как будто по какой-то причине последний супер (...). Save() не вызывается.

Однако, если бы я добавить еще блок внешний, если, например:

 if self.pk is None: 
      ... 
     else: 
      super(Person, self).save(*args, **kwargs) 

сохранения() будет работать, как и ожидалось для существующих объектов - изменен integervalue сохраняется в базе данных.

Я что-то упустил, или это правильное поведение? Является ли "self.pk None" действительно действительным индикатором того, что объект только создается в Django?

P.S. Я сейчас переписываю это в сигналы, хотя это поведение все еще меня озадачивает.

ответ

0

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

После тщательного изучения и даже поездки с pdb, я обнаружил, что исходный код имел смешанный отступ - \ t вместо \ s {4} перед последним супер(). Save().

0

Не стоит переоценивать метод save(). Django делает много вещей за сценой, чтобы убедиться, что объекты модели сохранены, как они ожидали. Если вы сделаете это неправильно, это принесет странное поведение и будет трудно отлаживать.

Пожалуйста, проверьте django signals, это удобный способ получить доступ к информации и статусу объекта модели. Они предоставляют полезные параметры, такие как instance, created и updated_fields, чтобы специально подобрать вашу потребность проверить объект.

+0

Я на самом деле переписываю этот бит в сигналы, спасибо за напоминание - добавит это как P.S. на вопрос. Вопрос заключается скорее в том, «почему это работает так, как работает». – RebelWithoutAPulse

+0

Лучше всего поставить отладчик pdb внутрь и пройти (я полагаю, вы знаете, как это сделать, но это почти тривиально, если вы не знаете). Я не могу визуально отлаживать ваш код. Возможно, ответ Алекса поможет, но, как я уже сказал, это очень легко испортить, переопределив метод 'save()'. –

0

Если ваш pk is None, супер save() вызывается дважды, что, я думаю, вы не ожидаете. Попробуйте эти изменения:

class Person(models.Model): 
    def save(self, *args, **kwargs): 
     is_created = True if not self.pk else False 
     super(Person, self).save(*args, **kwargs) 
     if is_created and self.some_field == 'Foo': 
      for otherModelInstance in OtherModel.objects.all(): 
       new_Intermediary_Model_instance = IntermediaryModel.objects.create(person = self, other = otherModelInstance) 
Смежные вопросы