访问 django urls.py 中的请求对象

Pax*_*Pax 2 python django django-views django-generic-views

该问题的灵感也来自此处的文档。

我在 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'),
]
Run Code Online (Sandbox Code Playgroud)

它给了我:

NameError:未定义名称“请求”

我知道。因为,请求对象由 URLConf 传递给 View 类/函数。那么,有没有办法,我可以在这个范围内访问user.id。

PS:如果我替换user__id=9. 它列出了用户 9 提出的所有问题。:)

Wil*_*sem 6

您通常通过做这个覆盖get_queryset方法中的子类ListView。所以你可以创建一个视图:

# 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(
            user_id=self.request.user.id
        )
Run Code Online (Sandbox Code Playgroud)

urls.py你然后使用QuestionListView

# app/urls.py

from django.urls import path
from app.views import QuestionListView

urlpatterns += [
    path('myqn/', QuestionListView.as_view(), name='myqn'),
]
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令定义函数或 lambda 表达式:

import inspect

def custom_queryset(*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(get_queryset=custom_queryset), name='myqn'),
]
Run Code Online (Sandbox Code Playgroud)

然而,这不是一个好主意。首先,它检查调用堆栈,如果稍后ListView更改,它可能不再起作用。此外,这里的列表视图不会检查用户是否已登录。我们不能使用方法解析顺序 (MRO)来调用super()方法。


注意:您可以使用LoginRequiredMixinmixin [Django-doc]将基于类的视图的视图限制为经过身份验证的用户 。