Django 클래스 기반 뷰 : as_view 메소드에 추가 매개 변수를 어떻게 전달합니까?


95

사용자 지정 클래스 기반보기가 있습니다.

# myapp/views.py
from django.views.generic import *

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

다음과 같이 슬러그 매개 변수 (또는 다른 매개 변수)를 뷰에 전달하고 싶습니다.

MyView.as_view(slug='hello_world')

이렇게하려면 메서드를 재정의해야합니까?

답변:


113

urlconf가 다음과 같은 경우 :

url(r'^(?P<slug>[a-zA-Z0-9-]+)/$', MyView.as_view(), name = 'my_named_view')

그러면 다음과 같이보기 함수 (예 : 'get_queryset') 내에서 슬러그를 사용할 수 있습니다.

self.kwargs['slug']

18
선택적 매개 변수 인 경우 예외를 방지하려면 다음을 사용하십시오.self.kwargs.get('slug', None)
Risadinha

6
이 "self.kwargs"가 언제 / 어디에 채워지는지 궁금합니다. 이것이 설정된 기본 클래스 함수를 찾고 있습니다.
binithb 2015

In github.com/django/django/blob/master/django/views/generic/… inclass View: def as_view(cls, **initkwargs): def view(request, *args, **kwargs):
Apollo Data

질문에 대답하지 않습니다.
Kireeti K

이 방법은 지금 지금 당신이 사용할 수있는, 사용되지 않습니다url('<slug:slug>', MyView.as_view(), name='my_named_view')
Rahat 자만을

91

as_view메서드에 전달되는 모든 매개 변수는 View 클래스의 인스턴스 변수입니다. 즉 slug, 매개 변수 로 추가 하려면 하위 클래스에서 인스턴스 변수로 만들어야합니다.

# myapp/views.py
from django.views.generic import DetailView

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel
    # additional parameters
    slug = None

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

MyView.as_view(slug='hello_world')작동 해야 합니다.

키워드를 통해 변수를 전달하는 경우 Erikkson이 제안한 내용을 사용 하십시오 . https://stackoverflow.com/a/11494666/9903


2
절대하지 마십시오 import *. 게시물을 수정했습니다.
holms

미래 독자의 계몽을 위해 @holms는 PEP8은 "와일드 카드 가져 오기 (<module> import에서 )는 피해야합니다"라고 말합니다. 필수만큼 강력하지 않아야하며 이것은 예입니다.하지만 예, 확실히 * 와일드 카드 가져 오기를 피해야합니다 . python.org/dev/peps/pep-0008/#imports

어디에서나 필수는 아니며 원하는 방식으로 원하는 것을 깨뜨릴 수 있지만 pep8은 단지 권장 사항 일 뿐이며 Python 커뮤니티에서는 추가 문제를 피하기 위해 가능한 한 이러한 모든 방법을 사용하는 것이 경험 법칙입니다. 코드를 커밋 할 때 내 linter는 항상 비어 있습니다.
holms

실제 변수에 대한 slug = 'hello_world'의 값은 무엇입니까?
Gonzalo Dambra

19

get_object()키워드 인수로 전달 된 슬러그를 기반으로 객체를 조회하기 위해 재정의 할 필요가 없다는 점은 주목할 가치가 있습니다 . https://docs.djangoproject.com/en/1.5/ref/ 의 속성을 사용할 수 있습니다. SingleObjectMixin class-based-views / mixins-single-object / # singleobjectmixin

# views.py
class MyView(DetailView):
    model = MyModel
    slug_field = 'slug_field_name'
    slug_url_kwarg = 'model_slug'
    context_object_name = 'my_model'

# urls.py
url(r'^(?P<model_slug>[\w-]+)/$', MyView.as_view(), name = 'my_named_view')

# mymodel_detail.html
{{ my_model.slug_field_name }}

(모두 slug_fieldslug_url_kwarg기본값은 'slug')


1
내 대답을 위키 대답으로 바꾸고 코드를 추가해야합니까?

15

템플릿의 컨텍스트에 개체를 get_context_data추가하려면 해당 컨텍스트에 재정의 하고 추가 할 수 있습니다 . request.user 가 필요한 경우 요청은 self 의 일부이기도합니다 .

def get_context_data(self, **kwargs):
        context = super(MyTemplateView, self).get_context_data(**kwargs)
        if 'slug' in self.kwargs:
            context['object'] = get_object_or_404(MyObject, slug=self.kwargs['slug'])
            context['objects'] = get_objects_by_user(self.request.user)

        return context

무엇입니까 MyObject?
Rob Kwasowski

13

urls.py https://docs.djangoproject.com/en/1.7/topics/http/urls/#passing-extra-options-to-view-functions 에서 매개 변수를 전달할 수 있습니다.

이것은 일반보기에서도 작동합니다. 예:

url(r'^$', views.SectionView.as_view(), { 'pk': 'homepage', 'another_param':'?'}, name='main_page'),

이 경우 뷰에 전달 된 매개 변수가 반드시 View 클래스의 인스턴스 변수 일 필요는 없습니다. 이 방법을 사용하면 기본 페이지 이름을 YourView 모델에 하드 코딩 할 필요가 없지만 urlconf에서 매개 변수로 전달할 수 있습니다.


고마워요, 이걸 꽤 오랫동안 찾고 있었어요!
Ilja

7

에서 언급 한 바와 같이 야로슬라프 Nikitenko 당신이보기 클래스에 새로운 인스턴스 변수를 하드 코딩하지 않으려면, 당신은 수있는 기능을 볼 수있는 추가 옵션 통과 에서 urls.py이 같은를 :

url(r'^$', YourView.as_view(), {'slug': 'hello_world'}, name='page_name')

보기에서 사용 방법을 추가하고 싶었습니다. 다음 방법 중 하나를 구현할 수 있습니다.

# If slug is optional
def the_function(self, request, slug=None):
    # use slug here

# if slug is an optional param among others
def the_function(self, request, **kwargs):
    slug = kwargs.get("slug", None)
    other_param = kwargs.get("other_param", None)

# If slug is required
def the_function(self, request, slug):
    # use slug here

1
Yaroslav Nikitenko 의 답변 에서 이것을 편집하고 싶었지만 거부되었으므로 필요할 때 누락 된 정보라고 느꼈기 때문에 직접 만들었습니다.
Emile Bergeron

게시물 주셔서 감사합니다! 편집을 거부 한 사람이 저 였는지, 왜 그런지 기억이 나지 않습니다.
Yaroslav Nikitenko

@YaroslavNikitenko 돌이켜 보면 편집하기에는 너무 컸고 새로운 답변의 형태로 답장하기에 최고였습니다.
Emile Bergeron

@EmileBergeron 초기 질문은 DetailView클래스 와 같은 일반적인 뷰에 관한 것이 었습니다 . 거기에서 어떻게 사용하는지 설명해 주시겠습니까?
bartaelterman

3

장고 3.0의 경우 이것이 저에게 효과적이었습니다.

# myapp/views.py
from django.views.generic import DetailView

class MyView(DetailView):
    template_name = 'detail.html'
    slug = None

    def get_object(self, queryset=None):
        self.slug = self.kwargs.get('slug', None)
        return queryset.get(slug=self.slug)

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('slug/<slug:slug>/', views.MyView.as_view(), name='myview_by_tag'),
]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.