在 Django 中访问请求对象 urls.py
Accessing request object in django urls.py
这个问题也受到文档here的启发。
我在 Django 中使用通用视图 (ListView) 以列出当前登录用户提出的所有问题。我很想在 views.py
中不创建视图的情况下执行此操作。所以在 urls.py 中我添加了一个路径,如:
urlpatterns += [
path('myqn/', login_required(views.ListView.as_view(model=models.Question, queryset=models.Question.objects.filter(user__id=request.user.id), template_name='testapp/question_list.html', context_object_name='questions')), name='myqn'),
]
它给了我:
NameError: name 'request' is not defined
我知道。因为,请求对象由 URLConf 传递给视图 class/function。那么,有没有办法,我可以在此范围内访问 user.id。
PS:如果我替换 user__id=9
,代码就可以工作。它列出了用户 9 提出的所有问题。 :)
您通常通过重写 ListView
的子类 中的get_queryset
方法来完成此操作。所以你可以创建一个视图:
# app/views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView
from app.models import Question
class QuestionListView(LoginRequiredMixin, ListView):
model = Question
template_name='testapp/question_list.html'
context_object_name='questions'
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
<b>user_id=self.request.user.id</b>
)
在 urls.py
然后使用 QuestionListView
# app/urls.py
from django.urls import path
from app.views import QuestionListView
urlpatterns += [
path('myqn/', <b>QuestionListView.as_view()</b>, name='myqn'),
]
您可以定义函数或 lambda 表达式:
import inspect
def <b>custom_queryset</b>(*args, **kwargs):
self = inspect.currentframe().f_back.f_locals['self']
return Question.objects.filter(
user_id=self.request.user.id
)
urlpatterns += [
path('myqn/', QuestionListView.as_view(<b>get_queryset=custom_queryset</b>), name='myqn'),
]
但这不是一个好主意。首先,它会检查调用堆栈,如果稍后更改 ListView
,它可能不再工作。此外,此列表视图不会检查用户是否已登录。我们不能使用 方法解析顺序 (MRO) 来调用 super()
方法。
Note: You can limit views to a class-based view to authenticated users with the
LoginRequiredMixin
mixin [Django-doc].
不,你不能。
as_view()
接受视图 任何 class 属性 class.在您的情况下,request
对象将无法从 class
访问
class Foo(ListView):
queryset = Question.objects.filter(<b>user__id=request.user.id</b>)
上面的代码片段你不能引用 request
因此你的 urls.py
如您所知,在这些复杂情况下,我们应该覆盖get_queryset()
。
这个问题也受到文档here的启发。
我在 Django 中使用通用视图 (ListView) 以列出当前登录用户提出的所有问题。我很想在 views.py
中不创建视图的情况下执行此操作。所以在 urls.py 中我添加了一个路径,如:
urlpatterns += [
path('myqn/', login_required(views.ListView.as_view(model=models.Question, queryset=models.Question.objects.filter(user__id=request.user.id), template_name='testapp/question_list.html', context_object_name='questions')), name='myqn'),
]
它给了我:
NameError: name 'request' is not defined
我知道。因为,请求对象由 URLConf 传递给视图 class/function。那么,有没有办法,我可以在此范围内访问 user.id。
PS:如果我替换 user__id=9
,代码就可以工作。它列出了用户 9 提出的所有问题。 :)
您通常通过重写 ListView
的子类 中的get_queryset
方法来完成此操作。所以你可以创建一个视图:
# app/views.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView
from app.models import Question
class QuestionListView(LoginRequiredMixin, ListView):
model = Question
template_name='testapp/question_list.html'
context_object_name='questions'
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
<b>user_id=self.request.user.id</b>
)
在 urls.py
然后使用 QuestionListView
# app/urls.py
from django.urls import path
from app.views import QuestionListView
urlpatterns += [
path('myqn/', <b>QuestionListView.as_view()</b>, name='myqn'),
]
您可以定义函数或 lambda 表达式:
import inspect
def <b>custom_queryset</b>(*args, **kwargs):
self = inspect.currentframe().f_back.f_locals['self']
return Question.objects.filter(
user_id=self.request.user.id
)
urlpatterns += [
path('myqn/', QuestionListView.as_view(<b>get_queryset=custom_queryset</b>), name='myqn'),
]
但这不是一个好主意。首先,它会检查调用堆栈,如果稍后更改 ListView
,它可能不再工作。此外,此列表视图不会检查用户是否已登录。我们不能使用 方法解析顺序 (MRO) 来调用 super()
方法。
Note: You can limit views to a class-based view to authenticated users with the
LoginRequiredMixin
mixin [Django-doc].
不,你不能。
as_view()
接受视图 任何 class 属性 class.在您的情况下,request
对象将无法从 class
class Foo(ListView):
queryset = Question.objects.filter(<b>user__id=request.user.id</b>)
上面的代码片段你不能引用 request
因此你的 urls.py
如您所知,在这些复杂情况下,我们应该覆盖get_queryset()
。