-1

(Django , Python) I have created a list of book objects and it is being passed as context in my views.py along with the current session. On my template, i was to check if the books in that list are stored in the session, and if they are i want to access some info relating to that book within that session. how do i access the books in the session dynamically? is there a way?

i know i can access them by using "request.session.name" (where "name" is the same of the space in the session it is stored)

There are several book titles saved in the session, the way they are saved are as follows (in a function under views.py)

request.session["random book title"] = "random dollar price" i want to access that "random dollar price" dynamically in a template.

this is the block of code in the template

{% for book in book_list %}
    {% if book.title in request.session %}
          {{ request.session.??? }}                      
    {% endif %}
{% endfor %}

Thank you in advance!

cahg88
  • 36
  • 4

3 Answers3

1

You can put session data in a dictionary and send this data to target template when you want to render it in view function.

def some_function(request):
        context={
          'data':sessionData #put session data here
        }
        return render(request,"pass/to/template.html",context)

Now you can access 'data' in your template.html

pooya
  • 155
  • 6
  • this is already done in my function, what i want to do is access the values dynamically in the template... i know i can access the values by "request.session."name" but i dont want to hardcode the "name" i want to do that dynamically... is there a way? – cahg88 Jul 14 '17 at 14:48
  • what do you mean by dynamically? could you explain a bit more ? – pooya Jul 14 '17 at 14:52
  • He needs to iterate in the template like `request.session.adventures_of_harkon`, `request.session.book_of_narnia`, etc where the `book_of_narnia` and such is actually coming from `book.title` – codyc4321 Jul 14 '17 at 14:55
  • this is very hard to do in django templates and almost always requires custom template tag – codyc4321 Jul 14 '17 at 14:55
  • correct, what codyc4321 said... exactly like that. Thank you codyc4321 – cahg88 Jul 14 '17 at 15:04
1

You can make a custom template tag to look up by attribute like here Performing a getattr() style lookup in a django template:

# app/templatetags/getattribute.py

import re
from django import template
from django.conf import settings

numeric_test = re.compile("^\d+$")
register = template.Library()

def getattribute(value, arg):
    """Gets an attribute of an object dynamically from a string name"""

    if hasattr(value, str(arg)):
        return getattr(value, arg)
    elif hasattr(value, 'has_key') and value.has_key(arg):
        return value[arg]
    elif numeric_test.match(str(arg)) and len(value) > int(arg):
        return value[int(arg)]
    else:
        return settings.TEMPLATE_STRING_IF_INVALID

register.filter('getattribute', getattribute)

Now change your template to

{% load getattribute %}

{% for book in book_list %}
    {% if book.title in request.session %}
          {{ request.session|getattribute:book.title }}                      
    {% endif %}
{% endfor %}

This is a basic custom template tag example:

Django - Simple custom template tag example

and docs:

https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/

From what I remember from my django days should work

codyc4321
  • 9,014
  • 22
  • 92
  • 165
0

I think you should just send a list of book names from your view instead of a queryset so when you are crosschecking with session you use the title directly instead.

{% for book in book_list %}
    {% if book in request.session %}
        {{ request.session.book }}                      
    {% endif %}
{% endfor %}
E. A.
  • 11
  • 5