Django get current view in template - python

How can I get the full name of the current view (my_app.views.index) in a template in Django 1.5?
With forms, I have an object called "view" in the template which I read using a template tag.
But with DetailViews I doesn't see anything similar.
Is there a way using a custom template processor?
Thanks
EDIT
Situation 1:
I retrieve a page, for example '/foo/bar/5/edit'.
Django will call 'foo.views.editbar' with pk=5.
This view renders an template 'foo/bar_form.html'
Situation 2:
If I retrieve '/foo/bar/new'
Django will call 'foo.views.newbar'
This view renders the same template as above ('foo/bar_form.html')
How can I check in this template 'foo/bar_form.html', from which view it has been rendered?
The result should be one of
'foo.views.editbar'
'foo.views.newbar'

Type just in view
{% with request.resolver_match.view_name as view_name %}
...
{{ view_name }}
...
{% endwith %}

I'm not sure I completely understand the requirement, but take a look at inspect.stack.
inspect.stack()[1][3]

Just set attribute to request object in view:
setattr(request, 'view', 'app.views.func')
and check this in template:
{% if request.view == 'app.views.func' %}
do something
{% endif %}
It worked for me.

Related

Django/Wagtail - How to create a conditional in template that checks for url path?

I'm struggling to finding a quick and easy solution to show HTML content based on a conditional that checks if the wagtail page is at root, aka '/'.
According to the Wagtail docs, I can also make this work using original request object from Django:
Additionally request. is available and contains Django’s request
object.
This is essentially what I want to do. I use the page object here from wagtail but it might be better if I used the request object from Django instead. How can I
{% if page.request.path == '/' %}
<div> show something </div>
{% else %}
#show nothing
{% endif %}
How can I structure a conditional to solve what I'm trying to do?
Access request
The request object can be accessed via request and not page.request.
A helpful tip is to add {% debug %} to see ALL the context that is available to the current template while working locally and debugging.
{% if request.path == '/' %}
<div> show something </div>
{% else %}
#show nothing
{% endif %}
More info
Within Wagtail the request object should be available to all templates, however you may need to enable this by following the instructions about Using RequestContext in the Django docs.
Alternatively this Django request in template answer provides a clear example of what to update in your settings file.

how to use django model object in django templates?

I am not able to use the Django model object in Django templates. I want to iterate using the model user in the template and then play with the ActivityPeriod(model) of that user. Please check my code for the clarity:
Here is my code:
views.py
from .models import User,ActivityPeriod
def call_response(request):
user = User.objects.all()
return render(request, "Test/list.html", {"users":user ,"activityperiod":ActivityPeriod})
Test/list.html
{% for user in users %}
'real_name': {{ user.real_name}}},
'activity_periods': {% with activity=activityperiod.objects.get(id =user) %}
{{ activity.start_time }}
{% endwith %}
{% endfor %}
But i am getting an error:
Could not parse the remainder: '(id' from 'activityperiod.objects.get(id'
What is the correct way? Can anyone please share it with me.
Django template don't understand the filter action of Model. This part shoud be in view.
activity=activityperiod.objects.get(id =user)
You should prepare your data and manipulate them before sending to template (a dictionary may help you). And remember that result of action "User.objects.all()" is a list.
views.py
def call_response(request):
user = User.objects.filter(user=request.user)
activityperiod = activityperiod.objects.get(user=user)
context={'user':user,'activityperiod':activityperiod}
return render(request, "Test/list.html",context})
Test/list.html
'real_name': {{ user.real_name}}
'activity_periods':{{ activityperiod.start_time }}
Your question suggests that you think you can a function in the templates like a normal function (ie activityperiod.objects.get(...)).
You can't, the templating system is not made like this (for security reasons amongst others).
You should do something like, in your models:
def call_response(request):
# ! first() not "all()" (if > 1 user, you'll have problem)!
user = User.objects.first()
activityperiod = activityperiod.objects.get(user=user)
return render(request, "Test/list.html",
{"users":user ,"activityperiod":activityperiod})

Creating a "Recent Posts" list in a sidebar.

I'm working on a simple blog app in Django, and i'm having trouble figuring out how to dynamically generate the five most recent posts in a side bar. Each of my views are class based and they extend a generic template, each view maps to one template which I believe is the correct way to do it. I've looked for a way to do this using template tags, but it seems Django doesn't like you to put any logic inside of your templates.
The problem I believe is that I want this to exist within my base.html because I want the recent posts to be displayed site-wide, is a view even supposed to map to your base.html or does that cause problems, i'm pretty new with this. I don't know how to approach this, whether i'm supposed to create a new view for base.html or if I should use my template tags, or if I should extend an existing view(but if I do that it won't be site wide?).
I essentially want the following(they're ordered in reverse chronological order)
{% for post in post_list[:4] %}
{{ post.title }}
{% endfor %}
You can use a template tag. More specifically, an inclusion tag is what you need. This allows you to insert a rendered snippet anywhere inside your template via a small view-like piece of code.
For example, create a templatetags/blog_tags.py file (it's important that you create the templatetags folder within your app; Django searches for them here by default) in your blog app and add the following:
from django import template
register = template.Library()
#register.inclusion_tag('blog/snippets/recent_posts.html')
def render_recent_blogposts():
return {
# This is just an example query, your actual models may vary
'post_list': BlogPost.objects.all().order_by("published_on")[:4]
}
now create a blog/snippets/recent_posts.html template (it can be anywhere as long as it mathecs the #register.inclusion_tag(...) above.):
<ul>
{% for post in post_list %}
<li> {{ post.title }}</li>
...
{% endfor %}
</ul>
finally, in your original template, you can now render your template tags:
<aside>
{% load blog_tags %}
{% render_recent_blogposts %}
</aside>

separate member and guest template content in django

I'm trying to figure out what is the best way to have mixes member and guest templates.
The main difference would be the menu of the page. In some languages i've worked with you can add prefixes to templates to get it to switch out the whole templates for the other version.
ex:
base.guest.html
base.member.html
In Django the only way i've seen any thing related to this is this code i found in the documents:
if request.user.is_authenticated():
# Do something for authenticated users.
else:
# Do something for anonymous users.
Is this the base way to do this in Django? or is there something else that i'm missing.
For most of my pages this would work out ok but wasn't sure if there was a better way to switch content based on authenticated state.
You don't extend in this case, instead you include. The base.html should authentication-agnostic.
{% if user.is_authenticated %}
{% include 'member.html' %}
{% else %}
{% include 'guest.html' %}
{% endif %}
If you want to, you can do have the if-statement also in your view, and pass the name of the template-to-be-included to the main template. For more info see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include

context KeyError in django templateTag

My app's templatetag code is throwing a KeyError for a missing key (page) in the context variable. In my template, I do not refer to context variables with context.variableKeyName, I just refer to variableKeyName (e.g. {% if is_paginated %}). And in my template, I can refer to the key page without any exceptions.
How should I get the context with the keys it needs into my templatetag?
Here are the details:
I am using django-profiles to return a list of some profiles:
url(r'^profiles/$', 'profiles.views.profile_list',
kwargs={ 'paginate_by':10 },
name='profiles_profile_detail'),
which calls this bit of code here:
https://bitbucket.org/ubernostrum/django-profiles..
In my template, I test {% if is_paginated %} before I call a templatetag:
{% if is_paginated %}{% load paginator %}{% paginator 3 %}{% endif %}
( I am using a templatetag inspired from http://www.tummy.com/.../django-pagination/ updated for django 1.3 http://djangosnippets.org/snippets/2680/ )
But this leads to the KeyError for 'paged'.
The documentation (comments in the class) of http://djangosnippets.org/snippets/2680/ says:
Required context variables: paged: The Paginator.page() instance.
It is also used in the template tag:
paged = context['paged']
You need to provide this context variable for this template tag to work. I think your best bet is to copy the code of profiles.views.profile_list view and add this context variable. It's unfortunately still a function-based view - otherwise extending it would have been a lot cleanier and easier.
the right way to code is:
{% paginator v 3 %}
v - variable that contains the db items

Categories