Django extend base.html along with its context - python

I've passed a variable to base.html from my views.py file in a context. I've extended this base.html to another several templates. The variable is only visible in the base.html and not any other extended template.
It does work if I pass the same context to each templates views.py file.
As I extended the base, shouldn't it also extend the variable? Is there any other way to get this working, or am I missing something?

When you extend a template, it inherits the html code. The context needs to be always injected by the view. If you want to pass always the same context, you need to subclass the view and not the template. You can write a mixin:
class GetContextViewMixin:
def get_context_data(self, *args, **kwargs):
return ['foo': 'foo'] # Replace with the real context
Then when you need the same context, you can use inheritance:
from django.views.generic import TemplateView
# The template of this view will obtain its context from the mixin method
class ExampleView(GetContextViewMixin, TemplateView):
template_name = 'foo.html'
If you want to extend the context in subclasses, you can override get_context_data (remember to call super):
from django.views.generic import TemplateView
class ExampleView2(GetContextViewMixin, TemplateView):
template_name = 'foo2.html'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['foo2'] = 'foo2' # Extend the context
return context

Related

Overriding get_context_data() is not working in child view

I am trying to override get_context_data() in a child class-based view to send more contextual data to the template, but it doesn't work. As a sample I am sending a test variable, but it is not rendered in the template.
class ProductList(LoginRequiredMixin, View):
template_name = 'product/product_scroll.html'
def get(self, request, *args, **kwargs):
#...
return render(request, self.template_name, data)
class Feed(ProductList):
template_name = "product/feed.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['test'] = 'sometestinfo'
return context
But in the template:
<p> Prueba: {{test}} </p>
is empty.
It's not working because you override get. Therefore the whole built in functionality of the view - including calling get_context_data - is bypassed. You almost never need to define the get or post methods.

Django contect_object_name is not producing a context dict in view

I am back with more django questions on CBVs. This is about context_object_name. I have the following:
#method_decorator(verified_email_required, name='dispatch')
class Create(CreateView):
model = Profile
context_object_name = 'profileForm'
template_name = 'Members/template_includes/profile/form.html'
form_class = ProfileForm
success_url = '/Members'
form_title = "New Login Profile Information"
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {
'profileTitle': self.form_title,
})
I am using PyCharm and can put a breakpoint in the template_name form and see what the environment knows about. I expect to see a dict named profileForm with all the form members in it plus profileTitle. Instead I see profileTitle as a standalone member. I do not see anything named profileForm or object_list and the expected form members are not being painted in the template.
I suppose that I understand that the extra content in the return render will pass a "naked" profileTitle but I did expect that the default get behaviour would pull in the form info.
Have I missed the point?
You've overridden the get method in your CreateView-subclass and in doing so, you've bypassed the included functionality that a CreateView does to fill your context. If you take a look here you can see that a CreateView would otherwise call return self.render_to_response(self.get_context_data()) (because it inherits from ProcessFormView) and it's within get_context_data() (ref) that those included context variables are set up.

How to retrieve data from an existing db file and display it on webpage using Django?

This is the views.py file:
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import Report
import random
class HomePageView(TemplateView):
def get(self, request, **kwargs):
args = {}
data = Report.objects.all()
args['data'] = data
return render(request, 'index.html',args)
I'm finding it difficult to understand the framework since I'm a beginner. So please help me.
You are trying to use class base view which will be different from function base view, to pass context data to template in class base view you need to override get_context_data method as below:
class HomePageView(TemplateView):
""" Home page view """
template_name = "index.html"
def get_context_data(self, **kwargs):
# first of all calling it's parent class method to get context (if any)
context = super(HomePageView, self).get_context_data(**kwargs)
# now you can update context dictionary as below:
context['data'] = Report.objects.all()
return context
Now you can access data in your template using {{ data }}
You can display the FileField content by passing the following
{{ context_obj.file_field_name.url }} in the template.

Django - using my context in render_to_response

Is there a way to call all my user data? without using all the template variables in my views
Templates:
{% csrf_token %}
<h1>Welcome {{user.full_name}} {{user.last_name}}</h1>
<h1>{{user.email}}</h1>
so in my views I'll use less code, by not declaring all the dict
views
return render_to_response('user/userhome.html', user)
For django version 1.8 or more you can directly access {{user}} in template. However you can add the following in the TEMPLATE_CONTEXT_PROCESSOR of your settings to access {{user}} directly in the template.
'django.contrib.auth.context_processors.auth',
You can use a dict-like object that defines __contains__ and __getitem__, but uses attribute access to set properties, eg.:
from django import shortcuts, template
from django.contrib.auth.decorators import login_required
class Page(dict):
# see http://stackoverflow.com/questions/4984647/accessing-dict-keys-like-an-attribute-in-python
def __init__(self, *args, **kwargs):
super(Page, self).__init__(*args, **kwargs)
self.__dict__ = self
#login_required
def foo(request):
page = Page()
page.user = request.user
return shortcuts.render_to_response('foo.html', page)
then you can write your template exactly the way you would like.

django-cbv serve password protected static content

For every user in my django application, I generate a static .ical file which I would like to serve. Is there a CBV for that and which method would I overwrite?
As all of my views are class based I' d rather not use a function-based view with a HttpResponse and a #auth_required decorator according to this:
Django: Serving a Download in a Generic View
Just inherit from the View model and override the view method.
class ICalDownload(View):
def get(self, *args, **kwargs):
# return your response just like you would in a function view.
If you want to protect the view, I like to use django-braces. Otherwise, you need to use method_decorator on the dispatch method:
#method_decorator(auth_required)
def dispatch(self, *args, **kwargs):
return super(ICalDownload, self).dispatch(*args, **kwargs)
At this point, a function based view might be a little simpler, but like you, I like to always use class based views.

Categories