Context not passed to overwritten templates - django

Django version 3.2.4
I'm trying to change the default index_title, site_header, and site_title used by the admin site. I've tried all the suggestions here, but the login page refuses to use the updated values. In fact, the required context (site_header in the example below) is empty (confirmed by overriding the template and using the {{ debug }} variable as described here) and the "default" value of "Django administration" is being used. A line from the template C:\Program Files\Python38\Lib\site-packages\django\contrib\admin\templates\admin\base_site.html:
<h1 id="site-name">{{ site_header|default:_('Django administration') }} a</h1>
I currently have all three variables overwritten in my app's admin.py file, and the updated values are being used after I've logged in, but it doesn't work on the initial login page:
admin.site.site_header = 'My Site Header'
admin.site.index_title = 'My Index Title'
admin.site.site_title = 'My Site Title'
I can override the base_site.html template and hardcode a value, but I would like to understand why that is necessary and figure out how I can pass some context to that overwritten template. I've tried all the methods of overriding the original context described here to no avail. That includes having a custom admin site which overrides the default admin site. I've also noticed that the each_context method is not being called on the initial login page, but it is called after I have logged in and I'm viewing an admin page.
I think some of the problem may stem from how I have my urlpatterns set up in urls.py. I have it set up like this so the URL displayed in the address bar for a login is the same for both the admin and non-admin portions of the site.
urlpatterns = [
path('', include('my_app.urls')),
path('login', auth_views.LoginView.as_view(template_name='admin/login.html')),
path('login/', auth_views.LoginView.as_view(template_name='admin/login.html')),
path('logout', auth_views.LogoutView.as_view()),
path('logout/', auth_views.LogoutView.as_view()),
path('admin/login', generic_views.RedirectView.as_view(url='/admin', permanent=True, query_string=False)),
path('admin/login/', generic_views.RedirectView.as_view(url='/admin', permanent=True, query_string=False)),
path('admin/logout', auth_views.LogoutView.as_view()),
path('admin/logout/', auth_views.LogoutView.as_view()),
path('admin/', admin.site.urls)
]
I'm also exclusively using the django_auth_ldap.backend.LDAPBackend:
AUTHENTICATION_BACKENDS = [
'django_auth_ldap.backend.LDAPBackend'
]
Any guidance would be appreciated.

I got around my problem by creating the following context processor:
from django.contrib import admin
def global_context(request):
"""
This is intended to be a global context processor. Any templates rendered from views using the
`django.template.RequestContext` context (the default context used by generic views) will have this context
available to them.
"""
context = {
'index_title': admin.site.index_title,
'site_header': admin.site.site_header,
'site_title': admin.site.site_title
}
return context
This in conjunction with setting admin.site.index_title, admin.site.site_header, and admin.site.site_title to the desired values in admin.py got things working as expected.

Related

Change URL Of Overridden Templates

On my website users access their accounts by going to the following address:
http://127.0.0.1:8000/users_area/username/profile
There they will find a button 'change password' (an overridden django template) which will take them to:
http://127.0.0.1:8000/accounts/password/change/
It is very small and I'm probably being too picky but is it possible to keep this overridden template but change its url? I'd instead like the change password url to be something like:
http://127.0.0.1:8000/users_area/username/password/change/
I've tried creating a template within my user's app, copying the 'change password' template content into there, then linking to it rather than to the overridden 'change password' template, but (obviously, in hindsight) it doesn't work.
I'll add as a side note. I actually have two user types, users and powerusers. Each has a unique and rather different 'users_area':
http://127.0.0.1:8000/users_area/username/profile
and
http://127.0.0.1:8000/powerusers_area/username/profile
If I get an answer to my above question I'm actually hoping to apply it to both of my different user types (shouldn't be hard but thought I should mention it).
Thank you.
In case you want to customize them, even have a customized MyUser model, you can still re-use a lot from Django like this
# authentication
path('user_register', user_register_view, name='user_register'),
path('login', login_view, name='login'),
path('logout', logout_view, name='logout'),
path('change_password', change_password_view, name='change_password'),
path('reset_password/',
auth_views.PasswordResetView.as_view(template_name="MyUser/password_reset.html"),
name="reset_password"),
path('reset_password_sent/',
auth_views.PasswordResetDoneView.as_view(template_name="MyUser/password_reset_sent.html"),
name="password_reset_done"),
path('reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(template_name="MyUser/password_reset_form.html"),
name="password_reset_confirm"),
path('reset_password_complete/',
auth_views.PasswordResetCompleteView.as_view(template_name="MyUser/password_reset_done.html"),
name="password_reset_complete"),
path('profile/<username>', profile_view, name='profile'),
You can do something like this
urls.py
from django.contrib.auth import views as auth_views
urlpatterns = i18n_patterns(
# other URLS
path('/users_area/username/password/change/', auth_views.PasswordChangeView.as_view, name='change_password'),
# more URLS from auth?
)

Custom login URL in django

I am a newbie in django and I was experting different options in Django. I have created a class based view which requires user authentication to view the web page. I am using the inbuilt LoginView.
When the url pattern is specified as follows
url(r'^login/', auth_views.LoginView.as_view(),name='login'),
it is correctly redirected to login page.
But when I give
url(r'^restaurant/login/', auth_views.LoginView.as_view(),name='login'),
I get a 404 when trying to access the page that requires user authentication.
But when I manually go to that url in browser, it works perfectly fine.
Why is that? Shouldn't it both cases work?
It sounds like you need to set LOGIN_URL in your settings:
LOGIN_URL = '/restaurant/login/'
or, it's better to use the URL pattern name, then you don't have to update your settings when you change the login URL
LOGIN_URL = 'login'
Not sure if I'd fully understand your question, just try to give a stupid answer.
Django 2.1.7
use namespace&url name in settings, if you have your own login view just change admin to your url namespace and name your view as 'login'
# settings.py
LOGIN_URL = 'admin:login'
then the login_required decorator will direct you the correct login page.
from django.contrib.auth.decorators import login_required
#login_required()
def month_archive(request, year, month):
production_list = Production.objects.month_archive(year, month)
context = {'production_list': production_list}
return TemplateResponse(request, 'production/production_list.html', context)
If it's a Class Based View, add decorator to urls.py
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('', login_required(views.ProductionList.as_view()), name='production-list'),
path('<int:year>/<int:month>/', views.month_archive, name='production-month'),
]

how to redirect from HomePage(Page) to your custom app model

I've created an app "Blog". In my app I've got several models including "BlogIndex(Page)". When I run local server I find myself at "home_page.html". What I want is to start my local server at "blog_index.html". I know that I can set a root page at settings>site>localhost to make my "blog_index.html" a root page, but I can't do this because in my app I've got some other models that live at the same level as "BlogIndex(Page)" and they are children of the root which is "HomePage" so it would brake my code. So my question is: can I make a redirect from "HomePage(Page)" to my "BlogIndex" so that when i start my server I would be automatically redirected from "HomePage" to "BlogIndex"? How can I do it? How much it will affect the performance of the site and it's optimization?
I know that there is settings>redirect but it works only for inactive pages, but i need "HomePage" to be active.
Thank you.
Perhaps a better approach would be to display your blog posts (and any other models you want) on your homepage. Just override get_context(). See here: Wagtail Views: extra context
Update:
You can redirect by overriding the serve() method. For example, in your model, you would do something like:
# home/models.py
...
from django.http import HttpResponseRedirect
from django.urls import reverse
class HomePage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
def serve(self, request):
# Redirect to blog index page
return HttpResponseRedirect('/blog/')
# only do this if you're using urls.py and namespaces
# return HttpResponseRedirect(reverse('blog:index'))
More info: http://docs.wagtail.io/en/latest/reference/pages/model_recipes.html?highlight=serve()#overriding-the-serve-method

How to get the name of current app within a template?

What's the simplest way to access the name of the current app within template code?
Alternatively, what's the simplest way to define a template variable to hold the name of the current app?
(The goal here is to minimize the number of places I need to edit if I rename an app.)
Since Django 1.5 there is a "resolver_match" attribute on the request object.
https://docs.djangoproject.com/en/dev/ref/request-response/
This contains the matched url configuration including "app_name", "namespace", etc.
https://docs.djangoproject.com/en/2.2/ref/urlresolvers/#django.urls.ResolverMatch
The only caveat is that it is not populated until after the first middleware passthrough, so is not available in process_request functions of middleware. However it is available in middleware process_view, views, and context processors. Also, seems like resolver_match is not populated in error handlers.
Example context processor to make available in all templates:
def resolver_context_processor(request):
return {
'app_name': request.resolver_match.app_name,
'namespace': request.resolver_match.namespace,
'url_name': request.resolver_match.url_name
}
There's a way to obtain an app name for a current request.
First, in your project's urls.py, considering your app is called 'main':
#urls.py
url(r'^', include('main.urls', app_name="main")),
Then, a context processsor:
#main/contexts.py
from django.core.urlresolvers import resolve
def appname(request):
return {'appname': resolve(request.path).app_name}
Don't forget to enable it in your settings:
#settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.request",
"main.contexts.appname",)
You can use it in your template like any other variable: {{ appname }}.

How to replace Pinax template view for home to a normal view?

I have just installed Pinax on Django 1.4.5 and in the urls the home page is a TemplateView. I want to add some logic in the home page so I commented that url and created a new one that links to a view called home. for the moment I do nothing in that view, I just want to reproduce the same behaviour as in the TemplateView, ie loading the template. The template loads but I loose the Pinax variables, as SITE_NAME (I did set the site name and it does appear when directly loading the template with the TemplateView).
This is the original url:
url(r"^$", TemplateView.as_view(template_name="homepage.html"), name="home"),
This is what I use:
url(r"^$", home, name="home"),
home is loaded from a freshly created app (with manage.py startapp, the folder is at the same level as manage.py, not inside the project's folder)
and the view connected to home is:
def home(request):
context = {}
return render_to_response('homepage.html', context)
If I add some context, like 'SITE_NAME': 'my site', the variables are filled correctly. But I would like to have them filled automatically just like before.
Even worse, when I try to login the home page still displays the 'logged out' version although the user is properly logged in (The account settings shows up correctly for the currently logged in user).
What did I do wrong?
You have reset the context when you are returning the response - since you didn't pass in an instance of RequestContext.
The quickest way to resolve this is to use the render shortcut, that automatically passes in the correct context:
from django.shortcuts import render
def home(request):
return render(request, 'homepage.html', {})