I need to pass a primary key from a newly created ModelForm
to another form field in the same view but I get an error. Any suggestions to make this work? It looks like in the past, this would be the answer:
def contact_create(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse(contact_details, args=(form.pk,))) else: form = ContactForm()
From the documentation, this is what is happening in the newer Django version > 1.8.3
p3 = Place(name='Demon Dogs', address='944 W. Fullerton') Restaurant.objects.create(place=p3, serves_hot_dogs=True, serves_pizza=False)
Traceback (most recent call last):
...
ValueError: save() prohibited to prevent data loss due to unsaved related object 'place'.
This is how I am getting my pk
from the view:
my_id = "" if form.is_valid(): # deal with form first to get id model_instance = form.save(commit=False) model_instance.pub_date= timezone.now() model_instance.user= current_user.id model_instance.save() my_id = model_instance.pk if hourformset.is_valid(): hourformset.save(commit=False) for product in hourformset: if product.is_valid(): product.save(commit=False) product.company = my_id product.save() else: print(" modelform not saved") return HttpResponseRedirect('/bizprofile/success')
This was introduced in Django 1.8. Previously you could assign not saved instance to One-To-One relation and in case of fail it was silently skipped. Starting from Django 1.8 you will get error message in this case. Check a documentation of Django 1.7 -> 1.8 upgrade.
It says:
Assigning unsaved objects to a ForeignKey, GenericForeignKey, and OneToOneField now raises a ValueError.
If you are interested in more details, you can check save
method in django.db.models.base
: Some part of it:
for field in self._meta.concrete_fields: if field.is_relation: # If the related field isn't cached, then an instance hasn't # been assigned and there's no need to worry about this check. try: getattr(self, field.get_cache_name()) except AttributeError: continue obj = getattr(self, field.name, None) # A pk may have been assigned manually to a model instance not # saved to the database (or auto-generated in a case like # UUIDField), but we allow the save to proceed and rely on the # database to raise an IntegrityError if applicable. If # constraints aren't supported by the database, there's the # unavoidable risk of data corruption. if obj and obj.pk is None: raise ValueError( "save() prohibited to prevent data loss due to " "unsaved related object '%s'." % field.name )
Last 5 rows are where this error is raised. basically your related obj
which is not saved will have obj.pk == None
and ValueError
will be raised.
it is simple:
p3 = Place(name='Demon Dogs', address='944 W. Fullerton') p3.save() # <--- you need to save the instance first, and then assign Restaurant.objects.create( place=p3, serves_hot_dogs=True, serves_pizza=False )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With