Pass data between different views in Django

Question:

I have a basic view that retrieves some data, renders my page and sends some data to this page:

def myview(request)

    one = values.objects.get(user=request.user).address
    two = values.objects.get(user=request.user).number

    return render(request, "main/mytemplate.html", 
                  context={'address': one, 'numbers': two})

So the values retrieved by those two queries are shown on my page.

Now, on the same page, called mytemplate.html, i’m using another view, which is supposed to handle a form and some other operations:

def secondview(request):

    if request.method == 'POST':
        if 'button1' in request.POST:
            form = MyForm(request.POST)
            # check whether it's valid:
            if form.is_valid():
                profile = form.save(commit=False)
                profile.user = request.user
                profile.save()
                return HttpResponseRedirect(request.path_info)


    else:
        form = MyForm()

    return HttpResponse('it works!')

How can i use the data retrieved by those two queries in the second view? The queries are executed when the page is loaded by the first view. Then, in the same page the second view is used. I want to use the two variables one and two in the second view. Is there a way to do this in Django?

Why don’t you make the same queries in the second view? Because i would like the second form to be as fast as possible in terms of reload, without having to do a DB query each time that view is used. Also, since i already retrieved those values when the page is opened, it would be a waste to do that again.

I don’t know if this question is clear enough, but the core of it is: can i pass variables/data between two views in django?

Asked By: Jack022

||

Answers:

Yes, you can use session to pass data across views. A session works like a temporary server storage and keeps the needed data in a dictionary form.

For instance, add the following lines to myview:

request.session['one'] = one
request.session['two'] = two

Then, retrieve the data in secondview by referring to the session:

one = request.session['one']
two = request.session['two']
Answered By: Arn

you can use cookies. but if you want more secure your request i suggest to you using redis and the python client for redis

file settings.py

redis = redis.Redis(host='localhost', port=6379, db=0)

file views.py

def view1(request):

    redis.set("foo", "boo")

def view2(request):

    boo = redis.get("foo")

You have few options:

  1. Simplest way: include this data in request to the second view (as part of the form data, see an example below). You might even use a single view: if POST was send – store data else do request and show it on a page.
  2. Use cache for that (see an example below) – But I’d recommend to use Django built-in package. Here is a basic example how to use it
  3. Use Django Sessions (see an example below) – it is working option despite of that they have another purpose. When customer is loaded Django will load full session record, so you’ll have all data in request.session variable. But that is bad practice: you can get a lot of data duplication and increased database memory consumption.
  4. Use API (e.g. using DjangoRestFramework) together with usual Django app. So you’ll just get data you need, and when you need. These API requests can also be cached so it is fast solution.
Answered By: wowkin2

Why not just saving the results of the two queries as hidden fields in the form rendered by the first template ?

<form ...>

    <input type="hidden" id="address" name="address" value="{{address}}">
    <input type="hidden" id="numbers" name="numbers" value="{{numbers}}">

    ...

Then, you can either add ‘address’ and ‘numbers’ form fields to MyForm

address = forms.CharField(widget=forms.HiddenInput(), required=False)
...

or just retrieve the values from request.POST

Answered By: Mario Orlandi

You might also be able to use request.META["HTTP_REFERER"] to pass variables between views if you can infer anything useful from the previous URL.

A class-based view example –

from django.views.generic import FormView

from . import forms


def parse_referrer(url: str) -> str:
    return "USEFUL_DATA"


class SecondView(FormView):
    template_name = "MY_TEMPLATE.html"
    form_class = forms.MY_FORM_CLASS
    def get_initial(self):
        referrer = self.request.META["HTTP_REFERER"]
        if "/SOME_URL/" in referrer:
            SOME_VARIABLE = parse_referrer(referrer)
            initial = {"SOME_VARIABLE": SOME_VARIABLE}
        else:
            initial = self.get_initial()
        return initial
Answered By: rdmolony