Может ли as_view () (для представлений на основе классов) быть реализован в декораторе? - PullRequest
1 голос
/ 17 августа 2011

Синтаксис Django as_view () для представлений на основе классов меня беспокоил.По сути, я устал от необходимости делать my_view = MyView.as_view () для каждого представления на основе классов, которое я хочу использовать (или помещать as_view () в каждую строку каждого URL-адреса, в котором я использую представления на основе c).Я думаю, что декоратор класса был бы более чистым способом реализовать это, и я пытаюсь выяснить, как добиться этого, для моего собственного кода и поделиться фрагментами django, на случай, если другие заинтересуются.Итак, мой вопрос: есть ли разумный способ реализовать декоратор as_view, чтобы следующий код был функциональным?

@as_view(my_view)
class MyView(View):
   pass

, что в основном эквивалентно:

class MyView(View):
   pass
my_view = MyView.as_view()

Спасибо, это также помогает мне изучить расширенные возможности (т.е. декораторы) Python.

Бен

1 Ответ

2 голосов
/ 17 августа 2011

Один подход, который приходит на ум, состоит в том, чтобы иметь декоратор класса просто setattr некоторый объект, который будет содержать все as_views, которые вы хотите определить. Вы можете использовать это в своем urls.py

import re

class Views(object):
    """Empty object for holding as_view method"""
views = Views()

def convert_name(name):
    """convert CapWords into cap_words"""
    return name[0].lower() + re.sub(r'([A-Z])', lambda m:"_" + m.group(0).lower(), name[1:])

def as_view(views):
    """Adds decorated class-based views' as_view methods to views container"""
    def decorator(cls):
        name = convert_name(cls.__name__)
        setattr(views, name, cls.as_view)
        return cls
    return decorator

И тогда в вашем views.py вы бы использовали его так:

from as_view_decorator import views, as_view

@as_view(views)
class MyView(View):
    ....

.. и MyView.as_view будут сохранены на объекте views как views.my_view.

Вы также можете сделать что-то подобное в своих views.py:

from as_view_decorator impor as_view
import sys; mod = sys.modules[__name__]

@as_view(mod)
class MyView(View):
    ...

Что бы установить my_view в качестве атрибута вашего views модуля. Вы могли бы тогда в вашем urls.py:

from app.views import my_view

urlpatterns = patterns('',    
    url(r'^$', my_view()),
)

Я думаю, что делать my_view = MyView.as_view довольно просто и легко читаемо, поэтому я бы, честно говоря, предпочел бы это сам.

...