Доступ к объекту запроса в django urls.py - PullRequest
2 голосов
/ 14 июля 2020

Вопрос также вдохновлен документацией здесь .

Я использую generi c view ( ListView ) в Django, чтобы вывести список все вопросы, которые задал текущий авторизованный пользователь. Мне было любопытно сделать это без создания представления в 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' не определено

Я знаю это. Поскольку объект запроса передается URLConf в класс / функцию View. Итак, есть ли способ получить доступ к user.id в этой области.

PS: Код работает, если я заменяю user__id=9. В нем перечислены все вопросы, заданные пользователем-9. :)

Ответы [ 2 ]

6 голосов
/ 14 июля 2020

Обычно это делается путем переопределения метода 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(
            <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'),
]

Вы можете определить функцию или лямбда-выражение с помощью:

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().

Примечание : вы можете ограничить представления представлением на основе классов для аутентифицированных пользователей с помощью LoginRequiredMixin mixin [Django -doc] .

2 голосов
/ 14 июля 2020

Нет, вы не можете.

as_view() принимает любые атрибуты класса класса представления. В вашем случае объект request не будет доступен из класса

class Foo(ListView):
    queryset = Question.objects.filter(<b>user__id=request.user.id</b>)

В приведенном выше фрагменте вы не можете ссылаться на request и, следовательно, также в свой urls.py

В таких типах сложных ситуаций мы должны игнорировать get_queryset(), как вы знаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...