Django 的 "request" 不是只有在显式调用时才有效吗?
Doesn't Django's "request" only work when explicitly called?
那是我的假设。但也有像 这样的例子,其中:
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post.html'
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.object is None:
return HttpResponseRedirect(reverse('blog'))
count_visits = None
unique_views = set()
if self.request.user.is_authenticated:
post_views = PostView.objects.filter(post=self.object)
count_visits = post_views.count()
for post_view in post_views:
unique_views.add(post_view.ip)
我尝试使用上面的代码,但出现错误 name 'request' is not defined
。我的代码(下面)搞砸了,但我想了解如何明确 request
以便基于 class 的视图上的表单可以工作(这是另一个 post):
class PostDetailView(generic.DetailView):
model = Post
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.object is None:
return HttpResponseRedirect(reverse('/'))
if self.request.user.is_authenticated:
comment_form = CommentForm(request.POST)
comment_form.save()
回溯:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/2/
Django Version: 3.2.5
Python Version: 3.9.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog.apps.BlogConfig',
'accounts.apps.AccountsConfig']
Installed 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']
Traceback (most recent call last):
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/detail.py", line 107, in get
context = self.get_context_data(object=self.object)
File "/Users/user/dev/assess_new/blog/views.py", line 97, in get_context_data
post = get_object_or_404(Post, pk=self.id)
Exception Type: AttributeError at /blog/2/
Exception Value: 'PostDetailView' object has no attribute 'id'
我注释掉了第 97 行并得到了这个(这促使我首先 post 这个问题):
name 'request' is not defined
Traceback (most recent call last):
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/detail.py", line 107, in get
context = self.get_context_data(object=self.object)
File "/Users/user/dev/assess_new/blog/views.py", line 111, in get_context_data
comment_form = CommentForm(request.POST)
Exception Type: NameError at /blog/2/
Exception Value: name 'request' is not defined
您不能 return get_context_data
中的 HTTP 响应对象。 Django 期望这个 return 是一个字典,而不是 HttpResponseRedirect
例如。
然而,如果没有这样的对象,您可以处理重定向,例如将其包装在 try
-except
对象中:
from django.core.exceptions import <strong>ObjectDoesNotExist</strong>
from django.shortcuts import redirect
class PostDetailView(generic.DetailView):
model = Post
context_object_name = 'post'
def get(self, request, *args, **kwargs):
try:
self.object = self.get_object()
except ObjectDoesNotExist:
return redirect('blog')
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
count_visits = None
unique_views = set()
if self.request.user.is_authenticated:
post_views = PostView.objects.filter(post=self.object)
count_visits = post_views.count()
for post_view in post_views:
unique_views.add(post_view.ip)
context.update(count_visits=count_visits, unique_views=unique_views)
return <strong>context</strong>
在get_context_data
方法中,你应该return一个字典,你可以向context
添加额外的项目,但最终它return是context
.例如使用 context.update(count_visits=count_visits, unique_views=unique_views)
调用。
那是我的假设。但也有像
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post.html'
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.object is None:
return HttpResponseRedirect(reverse('blog'))
count_visits = None
unique_views = set()
if self.request.user.is_authenticated:
post_views = PostView.objects.filter(post=self.object)
count_visits = post_views.count()
for post_view in post_views:
unique_views.add(post_view.ip)
我尝试使用上面的代码,但出现错误 name 'request' is not defined
。我的代码(下面)搞砸了,但我想了解如何明确 request
以便基于 class 的视图上的表单可以工作(这是另一个 post):
class PostDetailView(generic.DetailView):
model = Post
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.object is None:
return HttpResponseRedirect(reverse('/'))
if self.request.user.is_authenticated:
comment_form = CommentForm(request.POST)
comment_form.save()
回溯:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/2/
Django Version: 3.2.5
Python Version: 3.9.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog.apps.BlogConfig',
'accounts.apps.AccountsConfig']
Installed 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']
Traceback (most recent call last):
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/detail.py", line 107, in get
context = self.get_context_data(object=self.object)
File "/Users/user/dev/assess_new/blog/views.py", line 97, in get_context_data
post = get_object_or_404(Post, pk=self.id)
Exception Type: AttributeError at /blog/2/
Exception Value: 'PostDetailView' object has no attribute 'id'
我注释掉了第 97 行并得到了这个(这促使我首先 post 这个问题):
name 'request' is not defined
Traceback (most recent call last):
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/Users/user/dev/assess_new/venv/lib/python3.9/site-packages/django/views/generic/detail.py", line 107, in get
context = self.get_context_data(object=self.object)
File "/Users/user/dev/assess_new/blog/views.py", line 111, in get_context_data
comment_form = CommentForm(request.POST)
Exception Type: NameError at /blog/2/
Exception Value: name 'request' is not defined
您不能 return get_context_data
中的 HTTP 响应对象。 Django 期望这个 return 是一个字典,而不是 HttpResponseRedirect
例如。
然而,如果没有这样的对象,您可以处理重定向,例如将其包装在 try
-except
对象中:
from django.core.exceptions import <strong>ObjectDoesNotExist</strong>
from django.shortcuts import redirect
class PostDetailView(generic.DetailView):
model = Post
context_object_name = 'post'
def get(self, request, *args, **kwargs):
try:
self.object = self.get_object()
except ObjectDoesNotExist:
return redirect('blog')
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
count_visits = None
unique_views = set()
if self.request.user.is_authenticated:
post_views = PostView.objects.filter(post=self.object)
count_visits = post_views.count()
for post_view in post_views:
unique_views.add(post_view.ip)
context.update(count_visits=count_visits, unique_views=unique_views)
return <strong>context</strong>
在get_context_data
方法中,你应该return一个字典,你可以向context
添加额外的项目,但最终它return是context
.例如使用 context.update(count_visits=count_visits, unique_views=unique_views)
调用。