Reputation: 99
I am working on a web application which works with entities that all have their unique IDs.
I have a submit form for users to create these entities and this form is in several steps (i.e. view 1 redirects to view 2, etc... until the end of the submission process).
The first view will create the ID of the entity after form submission and I then need to use the ID of the instance created in the other views.
I do not want to pass this ID as a URL parameter to the other views as these will be POST and that means that users could easily manipulate these and create records in models for several IDs. I have managed to pass this ID to several views using the session parameters (request.session) but this is not ideal as this is permanent for the session. Current code below:
def view1(request):
if request.method == 'POST':
form = xxx_creation_form(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
... object creation ...
)
request.session['xxx_id'] = xxx_entry.id
return HttpResponseRedirect(reverse('form_2'))
else:
form = xxx_creation_form()
return render(request, 'xxx_form.html', {'form': form})
def view2(request):
xxx_id = request.session['property_id']
if xxx_id == 'SET_BACK_BLANK':
return render(request, 'no_xxx_id.html')
if request.method == 'POST':
form = xxx_form2(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
id = xxx_id, #use the id created in step 1
... rest of object creation ...
)
request.session['xxx_id'] = 'SET_BACK_BLANK' #to avoid the misuse during other user interactions.
return HttpResponseRedirect(reverse('thanks'))
else:
form = xxx_form2()
return render(request, 'xxx_form2.html', {'form': form})
Ideally, I would like to pass this ID parameter in the headers of the response as this will avoid having the ID as a session parameter. So I have amended the code to the below:
def view1(request):
if request.method == 'POST':
form = xxx_creation_form(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
... object creation ...
)
response = HttpResponseRedirect(reverse('form_2'))
response['xxx_id'] = xxx_entry.id
return response
else:
form = xxx_creation_form()
return render(request, 'xxx_form.html', {'form': form})
def view2(request):
xxx_id = HttpResponseRedirect(request).__getitem__('xxx_id')
if request.method == 'POST':
form = xxx_form2(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
id = xxx_id, #use the id created in step 1
... rest of object creation ...
)
return HttpResponseRedirect(reverse('thanks'))
else:
form = xxx_form2()
return render(request, 'xxx_form2.html', {'form': form})
However the above does not work and the error message seems to indicate that there is no 'xxx_id' in the response header.
It would be great if anyone could let me know how to access a response's header in a view as it seems that we cannot amend the request's headers.
Thanks.
Upvotes: 1
Views: 1267
Reputation: 599490
What you're asking doesn't really make sense. The response is what is sent from Django to the browser, it is not what the browser sends to Django. That's a completely separate request; in the case of a redirect, your response is simply an instruction to the browser to make that request to a new URL.
The correct thing to do is to use the session, as you are doing. If you are worried about the value being persisted, then pop it out of the session when you use it:
xxx_id = request.session.pop('property_id')
Upvotes: 1