I have a view that has context data and it extends base.html but as I want the context data to be displayed in all templates that extend from base.html and not only the view with the context data I am doing custom template tags with the context inside but I get an error.
view with and without context data:
class HomeView(ListView):
model = Product
context_object_name='products'
template_name = 'main/home.html'
paginate_by = 25
class HomeView(ListView):
model = Product
context_object_name='products'
template_name = 'main/home.html'
paginate_by = 25
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
categories = Category.objects.all()
news = News.objects.all()
context.update({
'categories' : categories,
'news' : news,
})
return context
base.html with and without the custom tag
{% news %}
{% for new in news %}
<p>{{ new.title }}</p>
{% endfor %}
The custom tag file templatetags/news.py
from django import template
from support.models import News
register = template.Library()
#register.inclusion_tag('news.html', takes_context=True)
def news(context):
return {
'news': News.objects.order_by("-date_posted")[0:25],
}
The custom tag file templatetags/news.html
{% for new in news %}
<p>{{ new.title }}</p>
{% endfor %}
File structure:
Project
main
templates/main
base.html
templatetags
news.py
news.html
models.py
urls.py
views.py
...
project
settings.py
...
...
You need to define the python code containing your tag codes in the TEMPLATES variable in settings.py.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
str(BASE_DIR.joinpath('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',
],
'libraries':{
'tagname': 'appname.news', # your template tag
}
},
},
]
Simple thing, you should load the template tag in news.html template which is registered.
Just load the tag in news.html template:
{% load tag_name %} #Add here tag name to load
Note: Please ensure that template tag setting is added in settings.py file
Regarding the question after the CURD Update test,
The bottom is my program. I create the editing part but when I want to save it after editing, it will keep reminding me that the email part is duplicated, but if I have id=5 (http://127.0.0.1:5757/polls) /5/edit/) Edit, but if I change the email, it will be a new ID after the update. How can I change it? Could you please remind me which error is wrong?
error message: This mail box already exists in the Store.
ps: You can read the pictures to understand the situation first.
update test Before modification: Before the modification, my content was empty .
update test after modification : After the modification, I fill in the text into the content field, it will show that This mail box already exists in the Store.
--models.py--
class Store(models.Model):
store_name = models.CharField(max_length=10)
store_holder = models.CharField(max_length=50)
store_phoneNumber = models.CharField(max_length=10)
store_address = models.CharField(max_length=100)
▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
store_email = models.EmailField(max_length=60,
default='',
help_text='need u', verbose_name='email account',
unique=True, )
▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
store_notes = models.TextField(blank=True, default='')
def __str__(self):
return self.store_name
def get_absolute_url(self):
return reverse('polls:polls_detail', kwargs={'id': self.id})
--froms.py--
from django import forms
from .models import *
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class StoreForm(forms.ModelForm):
class Meta:
model = Store
fields = '__all__'
--views.py--
def polls_edit(request, id=None):
# basic use permissions
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
instance = get_object_or_404(Store, id=id)
form = StoreForm(request.POST or None, request.FILES or None, instance=instance)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
# message success
return HttpResponseRedirect(instance.get_absolute_url())
context = {
'title': 'edit',
'instance': instance,
'form': form,
}
return render(request, 'polls/polls_form.html', context)
--urls.py--
from django.urls import path
from . import views
from django.contrib.auth import views as auth_view
# Create your urls here.
app_name = 'polls'
urlpatterns = [
path('profile/', views.polls_profile, name='polls_profile'), # http://127.0.0.1:8000/posts/list
path('edit/', views.polls_profile_edit, name='polls_profile_edit'), # http://127.0.0.1:8000/posts/3/edit/
path('changePassword/', views.changePassword, name='changePassword'), # http://127.0.0.1:8000/posts/3/edit/
# CURD
path('<int:id>/detail/', views.polls_detail, name='polls_detail'), # http://127.0.0.1:8000/posts/9/
path('create/', views.polls_create, name='polls_create'), # http://127.0.0.1:8000/posts/create
path('list/', views.polls_list, name='polls_list'), # http://127.0.0.1:8000/posts/list
path('<int:id>/edit/', views.polls_edit, name='polls_edit'), # http://127.0.0.1:8000/posts/3/edit/
# path('<int:id>/delete/', views.polls_delete, name='polls_delete'), # http://127.0.0.1:8000/posts/delete
path('delete/', views.polls_delete, name='polls_delete'), # http://127.0.0.1:8000/posts/delete
# else views
path('contact/', views.contact, name='contact'),
# path('', views.login_redirect, name='login_redirect'),
# path('register/', views.registration_view, name='register'),
path('register/', views.register, name='register'),
path('', views.starter, name='starter'),
path('login/', auth_view.LoginView.as_view(template_name='registration/login.html'), name='login'),
path('logout/', auth_view.LogoutView.as_view(template_name='registration/logged_out.html'), name='logout'),
# pw change
path('password_change/', auth_view.PasswordChangeView.as_view(), name='password_change'),
# pw change success
path('password_change/done/', auth_view.PasswordChangeDoneView.as_view(), name='password_change_done'),
# forget pw / set pw
path('password_reset/', auth_view.PasswordResetView.as_view(), name='password_reset'),
# forget pw / set pw success
path('password_reset/done/', auth_view.PasswordResetDoneView.as_view(), name='password_reset_done'),
#
path('reset/<uidb64>/<token>/', auth_view.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
# pw already change
path('reset/done/', auth_view.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
# pw sent
# path('reset_password_sent/', auth_view.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
--polls_forms.html
{% extends 'base_generic.html' %}
{% block body %}
<title>Form Page</title>
<!-- Content Wrapper. Contains page content -->
<div class='content-wrapper'>
{% if user.is_authenticated %}
<!-- Content Header (Page header) -->
<div class='content-header'>
<div class='container-fluid'>
<div class='row mb-2'>
<div class='col-sm-6'>
<h1 class='m-0'>Form Page</h1>
</div><!-- /.col -->
<div class='col-sm-6'>
<ol class='breadcrumb float-sm-right'>
<li class='breadcrumb-item'><a href='#'>Form</a></li>
<li class='breadcrumb-item active'>Form Page</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<div class='content'>
<div class='container-fluid'>
<div class='row'>
<div class='col-lg-6'>
<div class='card'>
<div class='card-body'>
<h1>Test</h1>
<form method='post' action='{% url 'polls:polls_create' %}'>
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='save'>
</form>
<div class='main'>
<!-- Display attributes of instance -->
{{ data.city }} <br/>
{{ data.description }}
</div>
<h5 class='card-title'>user account : {{ user|capfirst }}</h5><br>
{% if author_list %}
<ul>
{% for author in author_list %}
<li>
<a href='{{ author.get_absolute_url }}'>
{{ author }} ({{ author.date_of_birth }} -
{% if author.date_of_death %}{{ author.date_of_death }}{% endif %})
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p>There are no authors available.</p>
{% endif %}
</div>
<!-- /* card-body -->
</div>
</div>
<!-- /.col-md-6 -->
</div>
<!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content -->
{% else %}
<!-- Content Wrapper. Contains page content -->
<div class='content-wrapper pt-5'>
<h4>Register</h4>
</div>
<!-- /.content-wrapper -->
{% endif %}
</div>
<!-- /.content-wrapper -->
{% endblock %}
--settings.py--
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-7r4mj*$^bv(zj##+$d42&k$ax_6ps3*f=wc8f)96s1yn3!%^4$'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
'accounts',
'shops',
]
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',
]
ROOT_URLCONF = 'mysite.urls'
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',
],
},
},
]
WSGI_APPLICATION = 'mysite.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'restA_db',
'USER': 'postgres',
'PASSWORD': 'postgres5',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'zh-Hant'
TIME_ZONE = 'Asia/Taipei'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
# STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
'/var/www/static/',
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/dist/media_cdn')
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Redirect to home URL after login (Default redirects to /accounts/profile/)
LOGIN_REDIRECT_URL = '/polls/'
LOGIN_URL = '/accounts/login/'
# LOGOUT_REDIRECT_URL = '/accounts/logout/'
# crispy_forms
# CRISPY_TEMPLATE_PACK = 'bootstrap4'
# STMP Configuration
if DEBUG:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = '587'
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'georgiawang5332#gmail.com' # sender account
EMAIL_HOST_PASSWORD = '0704gta93julro' # sender password
--urls.py--
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
# from django.contrib.auth.views import login, logout
urlpatterns = [
path('polls/', include('polls.urls')),
path('shops/', include('shops.urls')),
path('admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
#Add URL maps to redirect the base URL to our application
from django.views.generic import RedirectView
urlpatterns += [
path('', RedirectView.as_view(url='/polls/', permanent=True)),
]
# Add Django site authentication urls (for login, logout, password management)
urlpatterns += [
path('accounts/', include('django.contrib.auth.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) ]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
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 %}
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 %}
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,
...
},
]