Концепция
Прежде всего, у меня есть довольно сложная модель ... Идея состоит в создании звездолета в качестве модели. Таким образом, каждый Корабль имеет тип (ship_type
), основанный на Плане этого Типа Корабля. Поэтому, когда вы создаете корабль, вы должны решить, какую ship_type
модель следует использовать (внешний ключ).
Потому что я хочу сменить корабль (пример: купить другое программное обеспечение), но не сам план. каждый корабль имеет те же поля в базе данных, что и корабль чертежей (оба наследуются от ShipField
). Когда кто-то устанавливает ship_type
или меняет его, я хочу, чтобы с Django до go план получил всю информацию и переписал информацию о корабле. Поэтому я попытался выполнить sh такое поведение в методе сохранения.
Поиск функций и ошибок
Функция, которую я написал, всегда запускается при изменении self.ship_type
, пока все хорошо. И все «нормальные» поля тоже изменены, только поля многие ко многим не работают.
Я нырнул в это и запутался. Предположим, что в нашем корабле нет записей в self.software
, а в новом ship_type
- 3. Если я распечатал self.software
до сохранения (1.), я получил, как и ожидалось, пустой набор запросов. Когда я делаю это после super.save (2.), я получаю набор запросов из трех элементов. Так что вроде бы все работает. Но если я взгляну на корабль в меню администратора, то на корабле вообще не будет программного обеспечения.
Заключение
Так что я пришел к выводу, что где-то после метода сохранения (возможно, в post_save) событие) программное обеспечение снова удаляется ... На данный момент мне нужна помощь.
Идеи
Я надеюсь, что вы, ребята, понимаете, что я пытаюсь сделать здесь. Я не эксперт по базам данных и могу представить, что есть лучшие способы добиться этого, поэтому я открыт для радикальных изменений.
Модели (упрощенно):
class ShipFields(models.Model):
body = models.ForeignKey(to=Body, verbose_name="Body", on_delete=models.SET_NULL,
null=True, blank=False, default=None)
software = models.ManyToManyField(Software, default=None, blank=True)
...
class ShipBlueprints(ShipFields, models.Model):
class Meta:
ordering = ['name']
verbose_name = "Ship Blueprint"
verbose_name_plural = "Ship Blueprints"
class Ship(ShipFields, models.Model):
name = models.CharField(max_length=256, unique=True)
ship_type = models.ForeignKey(to=ShipBlueprints, on_delete=models.SET_NULL, null=True)
...
__original_ship_type = None
def __init__(self, *args, **kwargs):
super(Ship, self).__init__(*args, **kwargs)
self.__original_ship_type = self.ship_type
def save(self, force_insert=False, force_update=False, *args, **kwargs):
# check if the ship type is changed
if self.ship_type != self.__original_ship_type:
...
# copy all fields from the related ShipBlueprints to the fields of Ship
# 1.
print(self.software.all())
self.body = self.ship_type.body
self.software.set(self.ship_type.software.all())
# or
# for soft in self.ship_type.software.all():
# self.software.add(soft)
# 2.
print(self.software.all())
...
super(Ship, self).save(force_insert, force_update, *args, **kwargs)
# 2.
print(self.software.all())
print(Ship.objects.get(name=self.name).software.all())
self.__original_ship_type = self.ship_type
Думаю, я сузил проблему. Когда я изменяю ship_type через администраторскую часть, many_to_many_fields не обновляется. НО, когда я изменяю ship_type через оболочку django, он работает отлично!
Когда я использую форму в представлении, он тоже работает. Так что мой код работает просто отлично, но страница администратора почему-то является проблемой ... Для меня это нормально, но похоже на ошибку в методе сохранения администратора, возможно, я сообщу об этом.
Спасибо всем за идеи.