Reputation: 714
I am submitting a form using 'post' and transferring its data to another view using request.POST but my querydict is incomplete when it arrives in the second view.
view1
def question_filter(request):
if request.method == 'POST':
print('before validation', request.POST)
request.session['question_data'] = request.POST
return HttpResponseRedirect(reverse('qapp:question_preview'))
view2
def question_preview(request):
all_questions = Questions.objects.all()
question_data = request.session.get('question_data')
print(question_data)
question_pk_list = question_data['question_pk']
preview_questions = all_questions.filter(id__in=question_pk_list)
...
return render(request,'apps/qapp/question_preview.html', {somecontext})
Am I doing something wrong here ?
Update:
before validation <QueryDict: {'topics_all': ['1', '2'], 'csrfmiddlewaretoken': ['...'], 'subtopics_all': ['4', '2'], 'classroom': ['3'], 'difficulty': ['l', 'm']}>
[28/Feb/2018 17:17:39] "POST /question/filter/ HTTP/1.1" 302 0
(in the second view)question data {'topics_all': '2', 'csrfmiddlewaretoken': '...', 'difficulty': 'm', 'subtopics_all': '2', 'classroom': '3'}
Upvotes: 2
Views: 450
Reputation: 557
This is somewhat old, but as I stumbled myself because of the same issue, I want to offer a solution for those reaching this question via a search, to storing the whole request.GET
or request.POST
object in a session without losing data (as opposed to @Exprator’s solution which requires handling each parameter manually).
The core issue is the default serializer Django uses for the session data: django.contrib.sessions.serializers.JSONSerializer
. This serializer is not aware of keys associated with multiple values (for them, the getlist()
method of QueryDict
should be used), which results in only the last value for each key being serialized.
There are two possible solutions:
request.GET
or request.POST
object when storing & retrieving from a session;
__getstate__()
method of QueryDict
, see also an old Django ticket.django.contrib.sessions.serializers.PickleSerializer
.Upvotes: 0
Reputation: 3884
The session is not saved by default. Add request.session.modified = True
:
def question_filter(request):
if request.method == 'POST':
print('before validation', request.POST)
request.session['question_data'] = request.POST
request.session.modified = True
return HttpResponseRedirect(reverse('qapp:question_preview'))
https://docs.djangoproject.com/en/2.0/topics/http/sessions/#when-sessions-are-saved
Edit:
You can hack it using json:
import json
def question_filter(request):
if request.method == 'POST':
print('before validation', request.POST)
request.session['question_data'] = json.dumps(request.POST)
return HttpResponseRedirect(reverse('qapp:question_preview'))
def question_preview(request):
all_questions = Questions.objects.all()
question_data = json.loads(request.session.get('question_data'))
print(question_data)
question_pk_list = question_data['question_pk']
preview_questions = all_questions.filter(id__in=question_pk_list)
...
return render(request,'apps/qapp/question_preview.html', {somecontext})
Upvotes: 0
Reputation: 27503
you cannot send all the post data
like that, as you have list inside your input names,
you have to access each names differently and set them in the session
.
request.session['question_data'] = request.POST.getlist('topics_all')
same for other input names
, then access with key in the second view
Upvotes: 2