Make an object exists in all templates - python

I have a django and I wrote some views. I know how to pass my variables to template, but I also has some external modules with their own views, which I wont modify. Please help me understand how can I get one of my object "Menu.objects.all()" exist in all templates? So for example a I have django-registration and i want to have all my menu items appear at top when someone visits not my app url. I mean it will be registration app url, which returns templateresponse (and here I dont have my variable).

You can add variables to context

The cleanest way to do it, is to use a Template Context Processor, which is a hook that will allow you to add things to your context before the template is rendered.
http://www.djangobook.com/en/2.0/chapter09.html
https://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors
Here's an example of Template Context Processors used in the django core:
https://github.com/django/django/blob/master/django/template/context_processors.py

Related

Subclassing and overriding Django Class based views

I'm building a website using django-all auth for it's authentication and social authentication functions. The forms that come bundled with the app are hardly great to look at and hence I decided to create my own views.
The problem is: How do I create them while ensuring that the backend of Django all auth is still available to me? I've dug into the source code and found that it uses class based views for rendering and performing CRUD operations.
I want to know if I can subclass those views in my own app/views.py and just change their template_name field to my own templates. Any advice would be most helpful.
Thanks.
You can of course subclass the views, as long as you change your URLs to point to the overridden versions. However, there is no need to do this just to use your own templates; Django's template loader is specifically written with this use case in mind. Simply create your own directory inside your templates folder to match the one allauth is using, and create your own template files inside it; Django will find yours first and use them.

Django decorator to redirect based on user-type

Currently in my django app, I have two kind of users, say userTypeA and userTypeB.
At this point, I redirect both of the types to /usercheck/ which has a function to check the type of user, and redirect them accordingly. This is working out pretty well.
However, just for curiosity, if I were to write a decorator where would I put it ?
One place I can think of is settings.py where a decorator will output different LOGIN_REDIRECT_URL based on the user type.
It is just for learning. My current implementation is working out pretty good so far.
Thanks a lot.
settings.py is meant for global static configuration data, I would definitely not try dynamically changing the settings. There are many other places in Django where a login url can be set explicitly.
I'm not entirely clear on what you want to do, but it sounds like the user_passes_test decorator is what you're after. From the docs:
Limiting access to logged-in users that pass a test: The simple way is to run your test on request.user in the view directly.... As a shortcut, you can use the convenient user_passes_test decorator.

Django templates, how do I know which template gets called

I'm using an external app in my django project which makes use of generic views, and I'm not able to figure out which template gets called for the response.
Do you know how to do that without having to dig into the source code of the app?
May be debugging the stack trace when the template gets loaded?
The Django debug toolbar will tell you.
Use debug-toolbar when you view a page it will show you the templates used.

Django: How to import variables in html templates

I have a django application and what I want to do is change wherever it says "Company id" in my templates. The thing it can be very tedious because I have to make this change in every template which says "Company id". So then I thought I might create another file that can store this entry, which the I can easy custom the company id.
config.py
company_no = "Company id"
This can work in my forms.py file. I can import company_no by saying
forms.py
from mmc.config import company_no
But then how can I do the same thing for templates? Importing company_no in a template - is there a way round?
This is what context processors are for. Define your company name in settings.py, then write a context processor that imports it from there and returns it in a dictionary - it will then be available in every template (as long as you use RequestContext to render the template).
As Blender stated, you need to pass variables like this in as part of the context when you render the template. You might make a dictionary or a namedtuple that has common items stored in configuration loaded in a function.
You should also consider using template inheritance if many templates will be display the same data, then you can have methods that load the pieces of context that go with certain base templates.
You could create a shared template and use include to load it in to the main template. Then in the shared template you could load and call a custom template tag that produces a context variable and render it as usual.
Alternatively, you could create a custom context processor that loads the data automatically in to the context instance and then render it as usual in the shared template.

django Authentication using auth.views

User should be redirected to the Login page after registration and after logout. In both cases there must be a message displayed indicating relevant messages.
Using the django.contrib.auth.views.login how do I send these {{ info }} messages.
A possible option would be to copy the auth.views to new registration module and include all essential stuff. But that doesn't seem DRY enough.
What is the best approach.
Update: Question elaboration:
For normal cases when you want to indicate to some user the response of an action you can use
request.user.message_set.create()
This creates a message that is displayed in one of the templates and automatically deletes.
However this message system only works for logged in users who continue to have same session id. In the case of registration, the user is not authenticated and in the case of logout since the session changes, this system cannot be used.
Add to that, the built in login and logout functions from django.contrib.auth.views return a 'HttpResponseRedirect' which make it impossible to add another variable to the template.
I tried setting things on the request object itself
request.info='Registered'
and check this in a different view
try:
info = request.info:
del request.info
except:
info = ''
#later
render_to_response('app/file',{'info':info})
Even this didn't work.
Clearly I can define a registered.html and add this static message there, but I was being lazy to write another template and trying to implement it DRY.
I realized that the cases were different for "registered" message and "logged out" message. And the DRY approach I used, I shall write as an answer.
If the messages are static you can use your own templates for those views:
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}
From the docs.
I think the best solution to this problem is to use a "flash"-type session-based messaging system. There are several floating around: django-flash seems really nice, I use django-session-messages which is very simple. Hopefully by the time we get to Django 1.2 this'll be baked-in.
You have Request Context Processors to add this kind of information to the context of every template that gets rendered.
This is the "zero impact" way to do this kind of thing. You don't update any view functions, so it meets some definitions of DRY.
See http://docs.djangoproject.com/en/dev/ref/templates/api/#id1
First, write your own login.html template.
Second, write your own context function to provide any additional information that must be inserted into the template.
Third, update settings to addy your context processor to the TEMPLATE_CONTEXT_PROCESSORS setting.

Categories