How to access RequestContext in class-based generic views? - django

I have this path in my urls.py:
archive_index_dict = {
'queryset': News.objects.filter(show=True),
'date_field': 'date',
'template_object_name': 'object_list',
}
...
url(r'^$', 'django.views.generic.date_based.archive_index',
archive_index_dict, name='news_archive_index'
),
Now I want to detect in template if a page is current (this is for menu styling). Neither {{ request.path }} nor {{ request.get_full_path }} work in template.
What should I use instead?
SOLUTION
To get request available in templates I had to add django.core.context_processors.request to TEMPLATE_CONTEXT_PROCESSORS. This is not set by default (since django 1.3).

Do you have 'django.core.context_processors.request' context processor set up? Almost all CBV use RequestContext by default

Related

Django: Is it possible to direct access objects from database inside a template

Is there any way to get a list of objects of one class without creating a dedicated view just using maybe TemplateView.as_view() and a template?
In fact, you need something, that will be returning a response object. That is what view actually is.
If you don't want to declare view as function or class, you can use lambda-functions.
Here is example of working urls.py:
from django.conf.urls import url
from django.contrib.auth.models import User
from django.shortcuts import render_to_response
urlpatterns = [
url(r'^test/$', lambda request: render_to_response('testapp/test.html', {'users': User.objects.filter()})),
]
I created anonymous function and returned response with objects I need and specified path to template.
Sure.
You can use assignment tag(write this in template tag library).
Assignment tag docs
#register.assignment_tag
def my_tag():
return Product.objects.all()
In template(TemplateView - no problem)
{% my_tag as my_tag %}
{% for item in my_tag %}
{{ item.name }}
{% endfor %}

Getting current active page in Django's Flatpages

I'm using flatpages to add my content.
I was wondering if there was a way to get the active page so I can style it properly on my navigational bar?
Thanks!
The flatpages app uses RequestContext, which means that details from the request are pushed up through the middleware. You can access these request variables in templates if the request template context processor is enabled. Once you enable this, then all your templates will have access to the request, and from there you can get the current requested URL.
So,
Enable the django.core.context_processors.request template context processor (its not enabled by default). You need to make sure you don't disable the default context processors, so add this to your settings.py:
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS as TCP
TEMPLATE_CONTEXT_PROCESSORS = TCP + (
'django.core.context_processors.request',
)
In your template, use {{ request.get_full_path }} or {{ request.path }} depending on what you need.
If your using django flat pages, then you will already have the URL's defined.
EG: url(r'^license/$', 'flatpage', {'url': '/license/'}, name='license'),
Using request.path_info should get you the current page. Is that what you where looking for is there of is it something else ?
<a href="{{ flatpage.url }}" {% if flatpage.url == request.path %}class="active-page"{% endif %}>{{ flatpage.title }}</a>
If you have issues with your request context, you can check Burhan Khalid's answer.

Django admin template: Accessing request object in template

I need the request object in all admin templates. In frontend templates, I can achieve this by rendering the template with RequestContext:
return render_to_response('my_template.html',
my_data_dictionary,
context_instance=RequestContext(request)
)
With that, I can access the request object in frontend:
{{ request.path }}
How can I do this for all admin views in Django 1.2?
The request should be available in the admin templates if you have 'django.core.context_processors.request' added to your TEMPLATE_CONTEXT_PROCESSORS in your settings.py

Is it possible automatically include user to all templates?

I have project in Django 1.3. In order to show username in all pages I use such tags in base.html
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}.
loggout</p>
{% else %}
loggin
{% endif %}
But if I dont return context_instance=RequestContext(request) from view value of user in template is empty. The 'django.contrib.auth.context_processors.auth' is included to TEMPLATE_CONTEXT_PROCESSORS.
Is it possible automaticaly include user to all templates?
since django 1.3. use shortcuts.render function and dont warry about requestcontext including to your views
You've given the answer yourself. As long as you use a RequestContext, it will be included in all templates.
If you really find that too much work, you could use the (new in 1.3) TemplateResponse class.
Or simply create a context processor. See
http://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors
Put this in context_processor.py
def root_categories(request):
return {
'user': request.user,
}
in settings.py add the context processor.
now in your template try: {{ user }}

passing additional arguments to django's login & template

My application uses Django's login view from django.contrib.auth.views.login, with a custom template I made.
I'd like to pass my template an additional argument which will change the login page in a few ways. Actually, I'm trying to show a different login page based on the URL.
How can I pass additional arguments to the login's view & to my custom template?
On Django 1.3 the login view accepts a new extra_context argument in the form of a dictionary.
django/contrib/auth/views.py
def login(request, template_name='registration/login.html',
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
To add to Roberto Rosario's answer, you can pass a dictionary of arguments to extra_context inside your urls.py
yourProject/urls.py
from django.conf.urls import url
from django.contrib.auth import views
urlpatterns = [
url(r'^login/$', views.login, {
'template_name': 'your-template-dir/login.html',
'extra_context': {
'additional_arg1': val1,
'additional_arg2': val2,
...
},
}, name="login"),
...
]
Which will then be available in your template.
yourProject/your-template-dir/login.html
{% extends "your-template-dir/base.html" %}
<div>
<p>The value of 'additional_arg1' is {{ additional_arg1 }}.</p>
<p>The value of 'additional_arg2' is {{ additional_arg2 }}.</p>
</div>
Here's Django's official documentation.
The source shows there is only one place that would influence the template context.
def login(request, template_name='registration/login.html',
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm): # here
So your only option is to hitch a ride on AuthenticationForm or write your own login view (which, by the way, is very simple if you look at the code).
from django.contrib.auth.forms import AuthenticationForm
AuthenticationForm.my_extra_data = 'foobar'
(r'^accounts/login/$', 'django.contrib.auth.views.login', \
{'template_name': 'myapp/login.html', \
'authentication_form': AuthenticationForm }),
Template
{{ form.my_extra_data }}
I was having an heck of time passing extra context variables from my custom login view-function to the template. They were all printing out as the empty string, despite following advice from a number of people a lot smarter than me.
Turns out my urls.py entry was still pointing to the built in login view, not my custom one.
Please don't let this happen to you.
When you eliminate the impossible, whatever remains, however improbable, must be the truth. -- Mr. Spock