Overriding a template in Django - python

I'm using this library to add a sessions tab on my django project. I'm calling the module's template from my project using this line:
<li>Sessions</li>
It works, but now I'd like to style the page, and to do that I need to override the module's template with my own template. So, as the module says here, I inherited the module's SessionListView on my own views.py to overrode the template:
from user_sessions.views import SessionListView
class MySessionList(SessionListView):
template_name = 'user_sessions/session_list.html'
Then I added the url to my urls.py
url(
regex=r'^account/sessions/$',
view=MySessionList.as_view(),
name='sessions',
),
And then I created my template on my own project which is located like this:
templates/user_sessions/session_list.
But for some reason, I still can't see MY template appearing, the module's template keeps appearing instead. Can anyone help me finding what I'm doing wrong?

The SessionListView already uses user_sessions/session_list.html by default, so your custom view isn't required.
It sounds like Django is finding the user_sessions/session_list.html template in the user_sessions app before your template. If your template is in an app's templates directory, then you can fix this by moving your app above user_sessions in your INSTALLED_APPS setting.
Alternatively, if you move your template to a directory in the 'DIRS' list in the TEMPLATES setting, then Django will find your template before it checks the app templates directories. This is cleaner if your overridden template doesn't really belong to any of your apps, and another advantage is that you don't have to re-order the INSTALLED_APPS list.
See the docs on overriding templates for more information.

Related

Override wagtail BaseSiteSetting template

I've been trying for some time to override the edit.html template for a single BaseSiteSetting in wagtail.
I'm not sure if this is even possible. My overrides for ModelAdmin templates are working just fine by using the following directory structure:
ModelAdmin index.html override
Is the same possible for my setting? Which is located in my success_stories app models.
I've looked through the wagtail/contrib/settings/templates/wagtailsettings/edit.html file but it's unclear to me how to do this. I've always worked with headless wagtail and don't have a lot of experience with templates.
The wagtail docs only seem to mention ModelAdmin overrides.
This would be done via standard Django template overrides: The first template that matches wins the cake.
In your case the template for the Wagtail Settings contrib module is located under templates/wagtailsettings/edit.html which means that in your app's template directory you have to make the exact same setup:
<you_app_directory>/templates/wagtailsettings/edit.html
Then depending on how you have setup your template discovery and/or have setup your app loading order one of the above templates will match first. So in order for your template to be the first one to match you can do two things:
Alter the loading order of your apps and make sure that your app comes before the wagtail.contrib.settings in your INSTALLED_APPS Django settings listing:
INSTALLED_APPS = [
...
<your_app>,
wagtail.contrib.settings
...
]
Or you can alter how templates are discovered by Django by changing the TEMPLATES setting:
TEMPLATES = [
{
...
'DIRS': [BASE_DIR / 'templates'],
"APP_DIRS": True,
...
},
]
Notice that DIRS comes before APP_DIRS, the order here matters as well. First Django will look in the directories you specify in DIRS, if nothing matched it will continue to look in the installed application directories.
Note that with the latter method BASE_DIR / 'templates' is a single templates directory at the root of your project.
Usually, if overriding third-party templates, the first method is used.

Django widget template override does not search in the project template directory. How to fix?

I am attempting to override a built in widget template in Django 1.11. I seem to be doing everything that the docs say to do in this regard, but for the widget templates, Django is not looking in my project at all, and I get a TemplateDoesNotExist error.
Here's what I have for the override:
class MyFileWidget(widgets.FileInput):
template_name = 'myapp/my_file_widget.html'
The template is definitely there. If I pass the template to a render call, it finds it fine. Problem is an issue of paths. When calling render from a view, it checks the following:
projectroot/templates/myapp/my_file_widget.html
djangoroot/forms/templates/myapp/my_file_widget.html
When it finds the template in my project, it renders it. This is NOT happening when I provide the template path in the class above. In that case, it does not check in my project templates, where the file actually exists, and begins checking in the django path, where it does not. Hence the error message.
So I have no clue why this the loader would check my project templates on render calls, but then fail to do so when looking for the "template_name" of the widget override. Any ideas?
By default, the FORM_RENDERER setting defaults to 'django.forms.renderers.DjangoTemplates'.
This checks your apps' templates directory (e.g. projectroot/myapp/templates/myapp/my_file_widget.html), but it does not check your project's template directories (e.g. projectroot/templates/myapp/my_file_widget.html).
If you want to use the same configuration as your TEMPLATES setting, then you should use the TemplatesSetting renderer.
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
You will also need to update your TEMPLATES setting so that Django can still use the built in widget templates. The easiest way to do this is to add django.forms to INSTALLED_APPS. See the docs for more info about this.

How do I define custom filters for minimal use of django templates?

I have a python project that I'm using Django templates for to generate C++ source code.
I picked Django because the template language is quite restrictive and has a very large community making it easy for end-use developers to use and get help with.
I'm failing to add custom filters for my project (to translate one set of type names into another) because I have not done the normal django setup.
Instead:
from django.template import Context, Template
import django
if not django.conf.settings.configured : django.conf.settings.configure()
django.setup()
Lets me use Django templates perfectly but not define custom filters.
My custom filter is called ctypes_filters.py and I reference it in the template as
{% load ctypes_filters %}
Running my generation script results in the following error:
django.template.base.TemplateSyntaxError: 'ctypes_filters' is not a valid tag library: Template library ctypes_filters not found, tried
django.templatetags.ctypes_filters
How can I get django to find the filter without setting up a full Django project (database definitions etc)?
I know that other templating solutions are available (and are probably more light-weight) but I'm really keen to use Django's simple and elegant templates.
The location of Django template tags is done by convention rather than a configuration setting (see the code layout section of the template tags docs).
Put the ctypes_filter.py in a templatetags directory in an installed app (I've called it myapp here). Add an empty __init__.py to both the myapp and templatetags directories. The app doesn't need any other files you might commonly find in a Django app, like models.py or views.py.
myapp/
__init__.py
templatetags/
__init__.py
ctypes_filter.py
Then include myapp in your INSTALLED_APPS when configuring your settings.
django.conf.settings.configure(
INSTALLED_APPS=('myapp',),
)

Creating Generic Views in Django

Ok so I am new to Django but not to the MVC world (built a few apps in Grails)...but I seem to be having the same issue as a bunch of people and I am hoping someone can shed some real light on Django's Class based generic views. In the Grails world "templates" or generic views CAN BE generated by the framework and I believe the same thing is true regarding Django but if you follow the 1.7 "Writing your first django app" there seems to be some special magic missing.
I have the following project/app structure:
mysite
->mysite
->settings.py
->urls.py
->_init_.py
->wsgi.py
->polls (my app)
->models.py
->urls.py
->views.py
->templates
->polls
In the tutorial we are asked to created an index.html, details.html, results.html file in the templates->polls directory and we have some simply HTML views within those files. That all works great. Once I get to "Use generic views: Less code is better" in the tutorial is where I get into trouble. Am I wrong in assuming I should simply REMOVE the index.html, details.html, results.html files from the templates folder AND that Django should be generating views on the fly? I assumed that was the point of the generic views but now I am not sure. When I do remove the views I get a templatedoesnotexist error. Do I need to do something to my settings.py to let it know that I want to look to django to generate the views? The following is the standard generated settings (which is what I have) and I assume that should be sufficient to perform default behaviors?
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DEBUG = True
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates/'),]
If you need more from me let me know, but basically I am wondering if I am way off on assuming Django generates the views from a template or not? Thank you!
You're just a bit confused about Django's terminology. Almost all views use a template to render the actual markup (HTML, XML, whatever) that is sent back to the browser.
A Django Generic View is just a Class based version of writing your own functional view. So instead of something like:
def show_template_with_data(request):
template = "myapp/show_data.html"
return render(request, template, {'data1': 1, 'data2': 2})
you would use Python classes and OO and do:
class ShowTemplateWithData(TemplateView):
template_name = "myapp/show_data.html"
def get_context_data(self, **kwargs):
context = super(ShowTemplateWithData, self).get_context_data(**kwargs)
context['data1'] = 1
context['data2'] = 2
return context
These two are equivalent one is just using functions and the other Class Based Views.
In Django, views are the code that determines what action is taken, what data is given to the template (for example based on logged in user), etc. a "template" is just the HTML with placeholders/loops/etc that displays it.
But no, you shouldn't be deleting the template HTML files, both styles of views will need them.

Custom django admin template for app

I would like to create a custom index.html derived from the admin/index.html individual for each app in my django project.
For instance my folder structure is like:
app1
templates
index.html (different from the global template admin/index.html)
app2
templates
admin
base.html
index.html (global template index.html)
How can I achieve custom admin index.html files for my apps, that are recognized by django? For the moment only the index.html in the global template/admin folder is considered for rendering the index pages in my backend.
I'm using django 1.6
Unfortunately, only certain parts of the Django admin site can be overridden on a per-app basis, as it says in the documentation:
Not every template in contrib/admin/templates/admin may be overridden per app or per model. The following can:
app_index.html
change_form.html
change_list.html
delete_confirmation.html
object_history.html
Remember that the admin interface is itself and app, so it's going to do a single template sweep and load the first set of templates that comes up.
I think your two best bets are either to use multiple admin sites in your project or to add a custom view for specific apps -- the former is probably easier, but will be a problem if you don't want people to have to login separately to control certain things.

Categories