Ниже упрощен пример того, что я пытаюсь достичь:вручную сохранение ModelForm относительные внешние ключи
class Product(models.Model):
# some data, does not really matter
class ProductAttributeValue(models.Model):
product = models.ForeignKey('Product')
value=models.CharField(_("value"),max_length=100)
....
class ProductForm(forms.ModelForm):
def __init__(self,*args, **kwargs):
super(ProductForm, self).__init__(*args, **kwargs)
#Here, I am dynamically constructing and injecting attributes.
#my products have dynamic attributes
# the filled-in values of these attributes need to be saved as ProductAttributeValue instances
#...
def save(commit):
m = super(ProductForm, self).save(commit=False)
#looping thru my custom attributes and constructing instances
#to simplify I will just put one example
attr_val=ProductAttributeValue(product=m)
attr_val.value=self.clean_data['myval']
m.productattributevalue_set.add(attr_val)
if commit:
m.save()
# also doing m2m_save if exists
return m
Итак, как я ожидал, что это терпит неудачу с product_id = None ошибка. Я также попытался понять, как работает InlineForm от django (на стороне администратора), но похоже, что они сначала сохраняют основной продукт, а затем ProductAttributeValue, и, если сказать, что сбой ProductAttributeValue не удается, они прекрасны. Для моего случая это неприемлемо, то есть либо я должен сохранить всю форму (как продукт, так и значение) или сбой. Я могу сэкономить с commit = True с самого начала, но, как я уже сказал, мне не нужен случай, когда продукт сохраняется, а значение - нет.
Любая помощь приветствуется.
Конечно, вы не можете добавить несохраненный экземпляр в другой несохраненный экземпляр. Что случилось с вызовом 'save()' и присвоением атрибута? Вы ожидаете, что это так или иначе сработает? Если да, то есть ответ ниже о транзакциях. Мне просто интересно, почему вы ожидаете неудачи здесь. Вы должны сделать проверку заранее, чтобы убедиться, что она не сбой на уровне базы данных. –