When used django_tables2, it told me TemplateDoesNotExist - python

urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.people),
]
views.py
def people(request):
return render(request, 'people.html', {'people': models.Person.objects.all()})
models.py
class Person(models.Model):
name = CharField(verbose_name="full name", max_length=10)
people.html
{% load render_table from django_tables2 %}
{% load static %}
{% render_table people %}
When I run it, it told me TemplateDoesNotExist at /django_tables2/table.html, I don't understand why.

First, make sure that django_tables2 is included in your INSTALLED_APPS setting.
Then, make sure that you have APP_DIRS set to True in your TEMPLATES setting.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [...],
'APP_DIRS': True,
...
},
]

Related

Django Model Forms ( Template Doesn't Exist)

I'm working on Django model forms. I have created forms.py and added the following:
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = [
'title',
'description',
'price'
]
And I have rendered this out in my views.py as it follows:
def product_create_view(request):
form = ProductForm(request.POST or None)
if form.is_valid():
form.save()
context = {
'form': form
}
return render(request, "products/product_create.html", context)
and I have added urls.py:
from django.contrib import admin
from django.urls import path
from pages.views import home_view , contact_view, about_view, social_view
from products.views import product_detail_view, product_create_view
urlpatterns = [
path('', home_view, name='home'),
path('contact/', contact_view),
path('admin/', admin.site.urls),
path('about/', about_view),
path('create/', product_create_view),
path('product/', product_detail_view),
path('social/', social_view),
]
I have migrated everything and saved all files, but when I want to go to my create URL, I get this error:
TemplateDoesNotExist at /create/
products/product_create.html
Request Method: GET
Request URL: http://127.0.0.1:8000/create/
Django Version: 3.2.4
Exception Type: TemplateDoesNotExist
Exception Value:
products/product_create.html
Exception Location: C:\Users\Invoker\dev\trydjango\env\lib\site-packages\django\template\loader.py, line 19, in get_template
Python Executable: C:\Users\Invoker\dev\trydjango\env\Scripts\python.exe
Python Version: 3.9.5
Python Path:
['C:\\Users\\Invoker\\dev\\trydjango\\src\\sadra',
'C:\\Program Files\\Python39\\python39.zip',
'C:\\Program Files\\Python39\\DLLs',
'C:\\Program Files\\Python39\\lib',
'C:\\Program Files\\Python39',
'C:\\Users\\Invoker\\dev\\trydjango\\env',
'C:\\Users\\Invoker\\dev\\trydjango\\env\\lib\\site-packages']
Server time: Wed, 23 Jun 2021 08:20:29 +0000
I have created a template as well:
{% extends 'base.html' %}
{% block content %}
<form>
{{ form.as_p }}
<input type='submit' value='Save' />
</form>
{% endblock %}
Templates in settings.py would be like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I have my templates in a folder called templates in the root directory. In there I have another folder called products which includes detail.html and product_create.html
What should I do?
I'm a little unclear as to your dir structure as you say "another directory", not a sub directory.
Good practice in Django is to nest dirs under a templates dir using the appname, so in our case
project/templates/products/product_create.html
Should do the trick.
You can have the templates folder in the project root, or you can have it in an app dir for dev (since you have set APP_DIRS to True), but you need to keep the same nesting structure.
As it stands, your project is simply not finding the correct template. Your view has the right path, but the template is in the wrong place.

Unable to override admin templates in Django 3.0

Here is my settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = '/static/'
And here is my template base_site.html in templates/admin/accounts/ (accounts is my app name):
{% extends "admin/base.html" %}
{% block title %}School name{% endblock %}
{% block branding %}
<h1 id="site-name">{{ site_header|default:_('Django administration') }}</h1>
{% endblock %}
{% block nav-global %}{% endblock %}
But this template is not overriding existing templates
In order to override the template templates/admin/base_site.html you have to have the same folder structure in your app.
You have myapp/templates/admin/accounts/base_site.html, but what you need is myapp/templates/admin/base_site.html. Then it should work.
The order of INSTALLED_APPS might be also important then.
-> Docs

How Django find correct Template variable from TemplateView

I have this pieces of code:
# newspaper_project/urls.py
from django.contrib import admin
from django.urls import path, include
from django.views.generic.base import TemplateView
urlpatterns = [
path('', TemplateView.as_view(template_name='home.html'), name='home'),
path('admin/', admin.site.urls),
path('users/', include('users.urls'))
path('users/', include('django.contrib.auth.urls')),
]
# users/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.SignUp.as_view(), name='signup'),
]
# users/views.py
from django.urls import reverse_lazy
from django.views import generic
from .forms import CustomUserCreationForm
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
<!-- templates/home.html -->
{% block title %}Home{% endblock %}
{% block content %}
{% if user.is_authenticated %}
Hi {{ user.username }}!
<p>logout</p>
{% else %}
<p>You are not logged in</p>
login |
signup
{% endif %}
{% endblock %}
And my question is:
How Django know what model is used in home.html template? (how Django know about "username"?)
In TemplateView i don't specify Model (in this case CustomUser). When we want to access and render database data, we need specify Model class (or in this case Form) in view. And from here Django accesses for template variable. Isn't it?
In your TEMPLATES setting, you have the auth context processor enabled.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
This adds user (the currently logged-in user or an anonymous user if not logged in) and perms (which stores the user's permissions) to the template context.
To setup a URL by doing path('', TemplateView.as_view(template_name='home.html'), name='home') is just about the simplest way to configure a view.
You wouldn't really do anything complicated with that, but you can specify some context variables using extra_context, for example;
path(
'',
TemplateView.as_view(
template_name='home.html',
extra_context={
'page_title': 'Home Page',
}
),
name='home'
)
To keep the urls.py clean you'd likely create another view for your home page and add your context variables that way;
class HomePageView(TemplateView):
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['page_title'] = 'Home Page'
context['user'] = CustomUser.objects.first() # Filter for user here
return context
<!-- templates/home.html -->
{% block title %}{{ page_title }}{% endblock %}
{% block content %}
{% if request.user.is_authenticated %}
Hi {{ request.user.username }}!
The user you were interested in is {{ user.username }}
<p>logout</p>
{% else %}
<p>You are not logged in</p>
login |
signup
{% endif %}
{% endblock %}
You can access the logged in user from the request object like this providing you have the request context processor in your settings;
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
...
'django.template.context_processors.request',
...
],
},
},
]

django_tables2 gives Tag {% querystring %} error although it is included in settings.py

I have this very simple django_tables2 setup that gives this error and I don't understand why (http://django-tables2.readthedocs.io/en/latest/pages/table-data.html#list-of-dicts):
Error:
Tag {% querystring %} requires django.template.context_processors.request to be in the template configuration in settings.TEMPLATES[]OPTIONS.context_processors) in order for the included template tags to function correctly.
settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(SETTINGS_PATH, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request', # <-- included
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
views.py:
import django_tables2 as tables
from django.views.generic.base import TemplateView
class RenderView(TemplateView):
template_name = "test.html"
def get_context_data(self, **kwargs):
context = super(RenderView, self).get_context_data(**kwargs)
data = [
{'name': 'Bradley'},
{'name': 'Stevie'},
]
table = NameTable(data)
context["table"] = table
return context
class NameTable(tables.Table):
name = tables.Column()
test.html:
{% load render_table from django_tables2 %}
{% render_table table %}
urls.py:
urlpatterns = [
path('', RenderView.as_view(), name='test'),
]
Apparently there is no request property:
def get_context_data(self, **kwargs):
print(self.request)
gives 'RenderView' object has no attribute 'request'
django 2.0.2, python 3.6
Try changing your load tags in your template to:
{% load django_tables2 %}
{% render_table table %}

Django context error in extended template called by view

I'm working in Django 1.11 with Django-Jet template.
Now I need to extend template in order to showing some data retrived from a view. So, I defined my template and my view.
Here is the code:
views.py
from django.shortcuts import render
from django.shortcuts import render_to_response
from django.views.generic import View
from django.template.context import RequestContext
from django.template import Context, Template
class MyView(View):
def get(self, request, *args, **kwargs):
op = str(self.kwargs['op']).strip().lower()
pk = self.kwargs['pk']
if op =='get':
template='frontend/templates/show_my_data.html'
return render_to_response(template,{'foo':'bar'})
else:
return HttpResponse("Not found")
My simple template:
{% extends "admin/base.html" %}
{% load i18n admin_urls static admin_modify %}
{% block content %}
{{ foo }}
{% endblock %}
settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'static/')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
....
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
But when I run a test I get a key error:
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/data_from_db/get/24/
Django Version: 1.11.2
Exception Type: KeyError
Exception Value:
'user'
Exception Location: /home/marco/sviluppo/myapp/myvenv/lib/python3.4/site-packages/django/template/context.py in __getitem__, line 87
Python Executable: /home/marco/sviluppo/myapp/myvenv/bin/python
So, I make some test, and I found that the problem is (maybe) in context variables. This is my base template that I need to be extended:
base.html
.....
{% if user.is_active and user.is_staff %}
{% jet_get_menu as app_list %}
{% if SIDE_MENU_COMPACT %}
{% for app in app_list %}
#print menu
{% endfor%}
.........
If I delete first condition: {% if user.is_active and user.is_staff %} there will be KeyError in {% jet_get_menu as app_list %}.
I'll show you some screen.
Normal admin template:
https://imgur.com/TKmc1mH
View result if I do not delete {% if user.is_active and user.is_staff %} from base.html template
https://imgur.com/BYtnEqM
as you can see the page is totally empty: no menu labels, no login box in top right corner, ecc.
There seems to be no context variables like user, but I do not understand why.
You need to use the render shortcut instead of render_to_response so that context processors are run.
if op == 'get':
template = 'frontend/templates/show_my_data.html'
return render(request, template, {'foo':'bar'})
You need to load jet_tags in every templates, you will be using them:
{% load jet_tags %}

Categories

Resources