(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!
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
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
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 %}
Related
I'm passing a dictionary from my view to a template. So {"key1":"value1","key2":"value2"} is passed in and looping through key,value pairs is fine, however I've not found an elegant solution from access directly in the view from a specific key, say "key1" for example bu json.items["key1"]. I could use some if/then statements, but I'd rather do directly is there a way?
Here is looping code in the html template:
{% for key, value in json.items %}
<li>{{key}} - {{value}}</li>
{% endfor %}
The Django template language supports looking up dictionary keys as follows:
{{ json.key1 }}
See the template docs on variables and lookups.
The template language does not provide a way to display json[key], where key is a variable. You can write a template filter to do this, as suggested in the answers to this Stack Overflow question.
As #Alasdair suggests, you can use a template filter.
In your templatetags directory, create the following file dict_key.py:
from django.template.defaultfilters import register
#register.filter(name='dict_key')
def dict_key(d, k):
'''Returns the given key from a dictionary.'''
return d[k]
Then, in your HTML, you can write:
{% for k in json.items %}
<li>{{ k }} - {{ json.items|dict_key:k }}</li>
{% endfor %}
For example, to send the below dictionary
dict = {'name':'myname','number':'mynumber'}
views :
return render(request, self.template_name, {'dict': dict})
To render the value in html template:
<p>{{ dict.name }}</p>
It prints 'myname'
To overcome this problem you could try something like this:
def get_context_data(self, **kwargs):
context['cart'] = []
cart = Cart()
cart.name = book.name
cart.author = book.author.name
cart.publisher = book.publisher.name
cart.price = 123
cart.discount = 12
cart.total = 100
context['cart'].append(cart)
return context
class Cart(object):
"""
Cart Template class
This is a magic class, having attributes
name, author, publisher, price, discount, total, image
You can add other attributes on the fly
"""
pass
By this way you can access your cart something like this:
{% for item in cart %}
<div class="jumbotron">
<div>
<img src="{{item.image}}" />
<div class="book_name"> <b>{{item.name}}</b></div>
<div class="book_by"><i>{{item.author}}</i></div>
<span>Rs. {{item.price}}</span> <i>{{item.discount}}% OFF </i>
<b>Rs. {{item.total}}</b>
{% endfor %}
I have some products listed which can be in a cart, this cart is stored in a session variable dictionary for which the key is the product id and the value is some information about the quantity and stuff. I want to add the option to view (on the products page) how many of that product are in your cart.
I know I can access session variables in a django template like this:
{{ request.session.cart.2323.quantity }}
Problem is, the key (2323 in this case) is a variable which depends on a for loop:
{% for prod in products %}
<p>{{ request.session.cart[prod.name].quantity }}</p>
{% endfor %}
But implementing it like that unfortunately is not possible. Is there any way in which this would be possible or would I have to change the way my cart works?
You should implement a custom template filter like this to have the ability to use getattr.
from django import template
register = template.Library()
#register.simple_tag
def get_object_property_dinamically(your_object, first_property, second_property):
return getattr(getattr(your_object, first_property), second_property)
{% load get_object_property_dinamically %}
{% for prod in products %}
<p>{% multiple_args_tag request.session.cart prod.name 'quantity' %}</p>
{% endfor %}
verified = models.BooleanField(default=False)
I want to show only that objects in frontend whose verified field is true in Django models.
There are many ways
you can handle this on your views
in views.py
modelList = modelname.objects.filter(verified=True)
also you can handle it on HTML
in views.py
modelList = modelname.objects.all()
in html
{% for models in modelList %}
{% if models.verified == True %}
# Your Code
{% endif %}
{% endfor %}
You filter the items with:
MyModel.objects.filter(verified=True)
with MyModel the model that contains the verified field.
you have to ways to achive that that either it with your views or html
first views
you can filter your model to return only object which is verfied like this
name = modelname.objects.filter(verified=True)
second way
or you can pass in html while you are requesting all object of that field in views
in views
name = modelname.objects.all()
then in html while fetching data
{% for name in models %}
{% if name.verified == True %}
then pass the object which are verified
{% else %}
pass another data
{% endif %}
{% endfor %}
i hope now you got my point tell me if you got any error while implementing any of these code
I want to create a template tag that passes in a dictionary of objects
models.py
class Notification(models.Models):
name = models.CharField()
..........
template_tag.py
created a template tag that gets all the objects that I want to display
from django import template
register = template.Library()
#register.simple_tag
def notifications():
context = {'notifications':Notification.objects.order_by('-date')[:4]}
return context
The later initiate a forloop that displays the objects
{% load template_tag %}
{% for obj in notifications %}
{{ obj.name }}
{% endfor %}
Hope you get the idea.....
Like in python:
{% for key, value in notifications.items %}
{{key}} - {{value}}
{% endfor %}
As simple as that!
After doing some research I have found that django as something called "inclusion_tag"
https://docs.djangoproject.com/en/3.2/howto/custom-template-tags/#inclusion-tags
create an html file and call it "notifications.html"
#register.inclusion_tag('notifications.html')
def notifications(total = 5):
context = {'notifications':Notification.objects.order_by('-date')[:total]}
return context
I'm working to add some business details as a context processor within an app called Business. I've included in it a folder titled templatetags for the __init__.py and business_tags.py files. My problem is while the context processor shows a result, I am unable to display the results as a loop.
business_tags.py file:
from django import template
register = template.Library()
from django.contrib.auth.models import User
from ..models import Businessprofile
#register.simple_tag
def my_biz(request):
current_user = request.user.id
biz = Businessprofile.objects.filter(owner=current_user)
return biz
On my view file I am currently made a for/endfor for the loop:
<!--content-->
{% load business_tags %}
{% my_biz request %}
{% for biz in my_biz %}
{{ biz }}
{% endfor %}
<!--end content-->
How do I display the results of the context processor as a for loop?
Your simple tag is just returning the object (it is not saved in "my_biz"), you need to save the return in a variable in this way:
{% my_biz request as my_biz_var %}
{% for biz in my_biz_var %}
{{ biz }}
{% empty %}
my_biz_var is empty
{% endfor %}
Aditional note: as is pointed by Daniel Roseman, what you are doing is not a context processor but a simple tag.
context procesors:
https://docs.djangoproject.com/en/1.11/ref/templates/api/#django.template.RequestContext
Simple tags:
https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/#simple-tags