我有一个关于Django导航栏的问题。我以前得到过关于如何修复tags.py
的帮助,但现在我得到了一个错误,上面写着:
Exception Type: KeyError
Exception Value: 'request'
Exception Location: /usr/lib/python2.7/site-packages/django/template/context.py in __getitem__, line 70
Python Executable: /usr/bin/python
我被告知要添加
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth'
)
在我的settings.py文件中,但错误仍然存在。
## file path
-- Main project folder
-- manage.py
-- .. other files ..
-- src
-- urls.py
-- settings.py
-- .. other files ..
-- templates
-- base.html
-- app folder
-- templates
-- app name
-- index.html
-- login.html
-- register.html
-- templatetags
-- __init__.py
-- tags.py
## urls.py
from django.conf.urls import patterns, url
from game import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^upload/$', views.upload_file, name='upload'),
url(r'^successful_upload/$', views.successful_upload, name='successful_upload'),
url(r'^play/$', views.play, name='play'),
url(r'^registration/$', views.register, name='register'),
url(r'^successful_registeration/$', views.successful_registeration, name='successful_registeration'),
url(r'^login/$', views.login, name='login'),
url(r'^logout/$', views.logout, name='logout')
)
## tags.py
from django import template
register = template.Library()
@register.tag
def active(parser, token):
import re
args = token.split_contents()
template_tag = args[0]
if len(args) < 2:
raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
return NavSelectedNode(args[1:])
class NavSelectedNode(template.Node):
def __init__(self, patterns):
self.patterns = patterns
def render(self, context):
path = context['request'].path
for p in self.patterns:
pValue = template.Variable(p).resolve(context)
if path == pValue:
return "-active"
return ""
## base.html
{% load tags %}
{% url 'index' as home %}
{% url 'upload' as upload %}
{% url 'play' as play %}
{% url 'register' as contact %}
{% url 'login' as login %}
<div id="navigation">
<a class="{% active request home %}" href="{{ home }}">Home</a>
<a class="{% active request upload %}" href="{{ upload }}">Upload</a>
<a class="{% active request play %}" href="{{ play }}">Play</a>
<a class="{% active request contact %}" href="{{ contact }}">Contact</a>
<a class="{% active request login %}" href="{{ login }}">Login</a>
</div>
## login.html
{% extends "base.html" %}
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="/game/login/" method="post">
{% csrf_token %}
<table border='0'>
<div class="fieldWrapper"><tr><td>
{{ form.user_name.errors }}</td><td></td></tr><tr><td>
<label for="id_user_name">User Name:</label></td><td>
{{ form.user_name }}</td></tr>
</div>
<div class="fieldWrapper"><tr><td>
{{ form.password.errors }}</td><td></td><tr><td>
<label for="id_password">Password:</label></td><td>
{{ form.password }}</td></tr>
</div>
</table>
<input type="submit" value="Login" />
</form>
## settings.py
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'xz6e)1=!%wma16h9$lt&gl8(96^(@1t2n)&lesteje_%x$+jn^'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_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',
'game',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'wam.urls'
WSGI_APPLICATION = 'wam.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/Chicago'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/static/'
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth'
)
# views.py
from django.shortcuts import render, render_to_response
from django.http import HttpResponse, HttpResponseRedirect
from django.core.context_processors import csrf
from django.http import Http404
from forms import UploadFileForm, UserRegisterForm, UserLoginForm
from game.models import UserLogin
def handle_uploaded_file(f, n):
with open('ais/' + n + '.py', 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
# Create your views here.
def index(request):
return HttpResponse("Hello, world. You're at the game index.")
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
post = request.POST
files = request.FILES
handle_uploaded_file(files['player1_ai_code'],
post['player1_ai_title'])
handle_uploaded_file(files['player2_ai_code'],
post['player2_ai_title'])
return HttpResponseRedirect('/game/successful_upload')
else:
form = UploadFileForm()
c = {'form': form}
c.update(csrf(request))
return render_to_response('game/upload.html', c)
def successful_upload(request):
return HttpResponse("The two ai's were successfully upload.")
def play(request):
import sys
sys.path.insert(0, 'ais')
sys.path.insert(0, '../tictactoe/')
import tictactoe
from html_change import *
s = tictactoe.play_game(ai=['ai1', 'randai'])
return HttpResponse(change(s))
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
post = request.POST
# check if the user exists in the database
check_user_exists = UserLogin.objects.filter(user_name=post['user_name'])
if check_user_exists:
c = {'form': form,
'error_message': "This user name already exists."}
c.update(csrf(request))
return render_to_response('game/register.html', c)
# check size of user name
if len(post['user_name']) < 5:
c = {'form': form,
'error_message': "Your username must be longer than 5 characters."}
c.update(csrf(request))
return render_to_response('game/register.html', c)
# check size of password
if len(post['password']) < 5:
c = {'form': form,
'error_message': "Your password must be longer than 5 characters."}
c.update(csrf(request))
return render_to_response('game/register.html', c)
# check if passwords match -- for the form
if post['password'] != post['re_password']:
c = {'form': form,
'error_message': "Your passwords do not match"}
c.update(csrf(request))
return render_to_response('game/register.html', c)
# registeration successful
user = UserLogin(user_name=post['user_name'], password=post['password'])
user.save()
return HttpResponseRedirect('/game/successful_registeration')
else:
form = UserRegisterForm()
c = {'form': form}
c.update(csrf(request))
return render_to_response('game/register.html', c)
def successful_registeration(request):
return HttpResponse("Your registration was successful")
def login(request):
if request.method == 'POST':
form = UserLoginForm(request.POST)
if form.is_valid():
m = UserLogin.objects.get(user_name=request.POST['user_name'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponseRedirect('/game')
else:
c = {'form': form,
'error_message': "Your username and password didn't match."}
c.update(csrf(request))
return render_to_response('game/login.html', c)
else:
form = UserLoginForm()
c = {'form': form}
c.update(csrf(request))
return render_to_response('game/login.html', c)
def logout(request):
try:
del request.session['member_id']
except KeyError:
pass
return HttpResponseRedirect("/game")
您应该在设置.py文件中从django.conf.global_settings
导入TEMPLATE_CONTEXT_PROCESSORS
,而不是定义一个新文件:
设置.py
from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
...
TEMPLATE_CONTEXT_PROCESSORS += ('django.core.context_processors.request',)
...
此外,上下文处理器只应用于RequestContext实例,因此您应该检查视图,并确保使用RequestContext
实例渲染模板:
from django.template import RequestContext
return render_to_response('base.html', {}, request_context=RequestContext(request))
或者更好的是,使用render
快捷功能:
from django.shortcuts import render
return render(request, 'base.html')
有关模板中上下文变量的详细信息,请参阅文档。