developer tip

Django 클래스 기반 뷰 (TemplateView)의 URL 매개 변수 및 로직

optionbox 2020. 9. 21. 07:37
반응형

Django 클래스 기반 뷰 (TemplateView)의 URL 매개 변수 및 로직


Django 1.5의 클래스 기반 뷰에서 URL 매개 변수에 액세스하는 것이 가장 좋은 방법이 나에게 명확하지 않습니다.

다음을 고려하세요:

전망:

from django.views.generic.base import TemplateView


class Yearly(TemplateView):
    template_name = "calendars/yearly.html"

    current_year = datetime.datetime.now().year
    current_month = datetime.datetime.now().month

    def get_context_data(self, **kwargs):
        context = super(Yearly, self).get_context_data(**kwargs)
        context['current_year'] = self.current_year
        context['current_month'] = self.current_month
        return context

URLCONF :

from .views import Yearly


urlpatterns = patterns('',
    url(
        regex=r'^(?P<year>\d+)/$',
        view=Yearly.as_view(),
        name='yearly-view'
    ),
)

year내 뷰 에서 매개 변수에 액세스하여 다음과 같은 로직을 수행 할 수 있습니다.

month_names = [
    "January", "February", "March", "April", 
    "May", "June", "July", "August", 
    "September", "October", "November", "December"
]

for month, month_name in enumerate(month_names, start=1):
    is_current = False
    if year == current_year and month == current_month:
        is_current = True
        months.append({
            'month': month,
            'name': month_name,
            'is_current': is_current
        })

위와 같은 CBV의 url 매개 변수에 가장 잘 액세스하는 방법은 위와 같이 하위 클래스가 TemplateView있으며 이상적으로 이와 같은 논리를 어디에 배치해야합니까? 방법으로?


클래스 기반 뷰에서 URL 매개 변수에 액세스하려면 self.args또는을 사용 self.kwargs하여 다음을 수행하여 액세스합니다.self.kwargs['year']


다음과 같은 URL 매개 변수를 전달하는 경우 :

http://<my_url>/?order_by=created

다음을 사용하여 클래스 기반보기에서 액세스 할 수 있습니다 self.request.GET( self.args또는에 표시되지 않음 self.kwargs).

class MyClassBasedView(ObjectList):
    ...
    def get_queryset(self):
        order_by = self.request.GET.get('order_by') or '-created'
        qs = super(MyClassBasedView, self).get_queryset()
        return qs.order_by(order_by)

I found this elegant solution, and for django 1.5 or higher, as pointed out here:

Django’s generic class based views now automatically include a view variable in the context. This variable points at your view object.

In your views.py:

from django.views.generic.base import TemplateView    

class Yearly(TemplateView):
    template_name = "calendars/yearly.html"
    # No here 
    current_year = datetime.datetime.now().year
    current_month = datetime.datetime.now().month

    # dispatch is called when the class instance loads
    def dispatch(self, request, *args, **kwargs):
        self.year = kwargs.get('year', "any_default")

    # other code

    # needed to have an HttpResponse
    return super(Yearly, self).dispatch(request, *args, **kwargs)

The dispatch solution found in this question.
As view is already passed within Template context, you don't really need to care about it. In your template file yearly.html, it is possible to access those view attributes simply by:

{{ view.year }}
{{ view.current_year }}
{{ view.current_month }}

You can keep your urlconf as it is.

Good to mention that getting information into your template’s context overwrites the get_context_data(), so it is somehow breaking the django's action bean flow.


So far I've only been able to access these url parameters from within the get_queryset method, although I've only tried it with a ListView not a TemplateView. I'll use the url param to create an attribute on the object instance, then use that attribute in get_context_data to populate the context:

class Yearly(TemplateView):
    template_name = "calendars/yearly.html"

    current_year = datetime.datetime.now().year
    current_month = datetime.datetime.now().month

    def get_queryset(self):
        self.year = self.kwargs['year']
        queryset = super(Yearly, self).get_queryset()
        return queryset

    def get_context_data(self, **kwargs):
        context = super(Yearly, self).get_context_data(**kwargs)
        context['current_year'] = self.current_year
        context['current_month'] = self.current_month
        context['year'] = self.year
        return context

How about just use Python decorators to make this intelligible:

class Yearly(TemplateView):

    @property
    def year(self):
       return self.kwargs['year']

참고URL : https://stackoverflow.com/questions/15754122/url-parameters-and-logic-in-django-class-based-views-templateview

반응형