0

Extremely new to web development, trying to pass user inputs in a form from one view to another using the session.

Session seems to reset after the HttpResponseRedirect in my "get_single_input" view, as I can retreive the "local_test" from the session. This set locally within the "single_output" view.

Read around and have even tried adding request.session.modified = True but not working....

Thank you for your time in advance.

from django.shortcuts import render
from django.http import HttpResponseRedirect

from .forms import single_input

def get_single_input(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
       # create a form instance and populate it with data from the request:
        form = single_input(request.POST)

        if form.is_valid():
            # Iterate through the form cleaned data and add it to the session instance.
            for k , v in form.cleaned_data.iteritems():
                request.session[ k ] = v

            request.session[ "test" ] = "test"

            request.session.modified = True

            # Then redirect to the single_output page
            return HttpResponseRedirect( "/single_output/" )



    else:
        form = single_input()

    return render(request, 'single_design/input_page.html', {'form' : form })


def single_output(request):

    request.session[ "local_test" ] = "local_test"
    sess_value = request.session.values()

    for v in request.session.itervalues():
        variable.append(v)

    for k in request.session.keys():
        del request.session[ k ]

    return render(request, 'single_design/output_page.html', { "variable" : variable , "sess_value" : sess_value})

settings.py as requested

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '866e09kpk%a(k9&nrtk79#=54o_04)=9il=2r4b2etf4k#f!xm'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions', # This imports sessions for use 
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'single_design', # Importing my app
    ]

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'primers.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'primers.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Europe/London'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join( BASE_DIR , 'static' )

Input page that renders the input form

{% extends 'single_design/base.html' %}
{% block content %}


    <body>

      <form action="/single_output/" method="post">
        {% csrf_token %}
        {{ form }}
      <input type="submit" value="Submit" />
      </form>

    </body>

{% endblock %}

Output page where I loop through the list that i have appended session items to.

{% extends 'single_design/base.html' %}
{% block content %}

    <body>
      this is the output page
    </body>

    {% for x in variable %}
      {{ x }}
    {% endfor %}

{{ sess_value }}
{% endblock %}
user3234810
  • 482
  • 2
  • 5
  • 18
  • 1
    You are setting a key named 'test' and trying to read a key named 'test_local'. – Abhinav Apr 10 '16 at 02:50
  • Hi, the "test" key is set intentionally in the first view to see if I can pass it on (incase my form data isn't working) while the "test_local" is set in the second just to make sure the session request is working. The loop in the second view should actually pull both "test" and "test_local" but when I load up the page only "test_local" is printed. – user3234810 Apr 10 '16 at 02:54
  • 1
    Can you update your post with the contents of settings.py? – Abhinav Apr 10 '16 at 03:00
  • Done, I was thinking of enabling the session save on every input however did some reading and the Django documentation states that by setting request.session.modified to True this would prompt a session save. – user3234810 Apr 10 '16 at 03:05
  • 1
    Ok, where is it failing? what are you trying to do on the single_output? where do you check that the session stuff is missing? Because you are deleting all the keys from the session in the single output, and you are not passing the keys themselves into the variable array as you are passing only the values – Aquiles Apr 10 '16 at 03:17
  • In the second view I loop through the items in the session and then append them to that list (for now, just for ease as i only picked django up this evening). I then loop through the list in the HTML output page. I will put the code for each page up now just incase im making a mistake there. EDIT: the only thing appearing on the output web page (from the loop) is "local_test". – user3234810 Apr 10 '16 at 03:19
  • For the moment I am only interested in the values, once I can pass session items from one view to another then I will expand this. I append all the current session values to the list, then clear them (as im refreshing a lot to test and rather than overwriting the session stuff I thought it best to clear it every time I re-submitted, I know this is not a great way of testing this out but as I mentioned I am quite new to this). – user3234810 Apr 10 '16 at 03:27
  • 1
    Your variable 'variable' doesn't seemed to be initialized. Can you try putting print(request.session.values()) at the beginning of single_output view and see if the values are in there? – Abhinav Apr 10 '16 at 03:30
  • I have added sess_value = request.session.values()) and passed this on in the render and html output = this is the output page 1 local_test ['local_test'] . In tests I am going to the input page in browser, entering some form values and then pressing the submit button which redirects me to the output page. – user3234810 Apr 10 '16 at 03:42
  • Edited the code to reflect current state. see second view and the output page. As mentioned in previous comment the browser displays " this is the output page 1 local_test ['local_test'] ". I can upload this to a GIT repo if you want to do some testing locally? EDIT - So the locally (within the single_output view) set session item is being appended to the list correctly, however it seems that anything in the "single_input" view session is lost. – user3234810 Apr 10 '16 at 03:46
  • Considering using something like [Session out of view](http://django.readthedocs.org/en/1.2.X/topics/http/sessions.html#using-sessions-out-of-views) – user3234810 Apr 10 '16 at 03:52

1 Answers1

2

I can think of only one scenario - that your form is never valid. So the condition where you check form.is_valid() is always failing.

Try setting the test key before that:

form = single_input(request.POST)
request.session['test'] = 'test'
if form.is_valid():
    ...
Abhinav
  • 622
  • 6
  • 15
  • I took set it outside the if request.method == "POST" and it worked!!! So is it in my input page HTML code that I redirect to the second page when I press the button?? If so how do i get it to "POST" ? – user3234810 Apr 10 '16 at 04:12
  • 1
    No, with your current code, you need to post back to the same view. Just remove the 'action' attribute in your form. Now when you hit submit, you should get your form data in request.POST. – Abhinav Apr 10 '16 at 04:18