Найти - Пользователи
Полная версия: Собственные (не основанные на CBV) классы для вьюх
Начало » Django » Собственные (не основанные на CBV) классы для вьюх
1 2
Elaphe
Пишу вьюху, которая представляет собой один класс, в нем несколько методов.
Некоторые методы принимают поступивший request и что-то там с ним делают (конкретно - парсят и обрабатывают пришедщий в нем json). То есть общий вид примерно такой:
 class MyView():
    def __init__(self):
        ...
    def first_function(self, request):
        try:
            data = json.loads(self.request.body)
        ...
        return HttpResponse('Hello world!!!')
Но в таком виде невозможно сослаться на first_function в файле urls - ругается на то, что нельзя использовать метод класса без указания инстанса.
Попробовала сделать через декоратор @classmethod:
 class MyView():
    def __init__(self):
        ...
    @classmethod
    def first_function(cls, **initkwargs):
        self = cls(**initkwargs)
        try:
            data = json.loads(self.request.body)
        ...
        return HttpResponse('Hello world!!!')
И во вьюхе:
 urlpatterns = (url(r'^info/$', MyView.first_function()),)
Ругается на то, что
MyClass instance has no attribute ‘request’' is not a callable or a dot-notation path
Как сделать так, чтобы оно работало? В смысле - может, ему явно request передать (как?) Или как ему инстанс передать, вызывая метод из urls.py?
Если кинете пример какого-либо самописного класса, отдельные функции которого являются вьюхами (и не основанного на CBV) буду весьма благодарна.
scidam

 #views.py (the app named `two`)
from django.http import HttpResponse
# Create your views here.
class CoolClass:
    @staticmethod
    def my_view(request):
	return HttpResponse('I was envoked inside CoolClass!')


 #urls.py (main project)
from two.views import CoolClass
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', CoolClass.my_view)
]
Elaphe
А как тогда ссылаться на другие методы внутри CoolClass? Не оборачивать же все в staticmethod
FishHook
Elaphe
Все это несколько не так работает
у класса представления есть статический метод as_view, который возвращает функцию, в которой создается объект этого класса и возвращается респонз. Вот эта функция и есть представление.
Если коротко
 class View(object):
    @classmethod
    def as_view(cls):
          obj = cls()
          def view(request):
                 response = obj.dispatch()
                 return response
          return view
   def dispatch():
         return Response()

когда ваши вьюхи - функции, то все просто, когда классы - то as_view возвращает такую же функцию. А вся логика происходит при вызове dispatch в теле этой функции. Диспатч вызывается уже не у класса, а у объекта, поэтому там есть self и работаеют методы объекта.
Elaphe
Разве это не касается только CBV?
Кроме того, как быть, если класс должен обеспечивать несколько представлений?
Или проще не сношать себе мозг и оставить все в виде функций?
FishHook
Elaphe
Разве это не касается только CBV
CBV - это представления основанные на классах. Какая разница, какой это класс: из состава джанги или ваш собственный. В любом случае в урл-паттерне должна быть функция (это API джанги), и даже в случае представленя-класса это должна быть функция. И где её взять? Только сделав один из методов класса статическим (точнее методом класса). Чем вам не нравится встроенная реализация? Возьмите базовый класс View и наворачивайте его как вам угодно. По-другому всё равно вряд ли получится. Можно, конечно, попробовать сделать синглтоны, но это приведет к возможности хранить состояние объекта между сессиями, то есть в продакшене при нескольких запущенных процессах вы получите непредсказуемое поведение.
FishHook
Elaphe
Кроме того, как быть, если класс должен обеспечивать несколько представлений?
Вас никто не принуждает вызывать именно as_view(). Наделайте as_view1(), as_view2() и т.д. Но зачем?
Elaphe
Или проще не сношать себе мозг и оставить все в виде функций?
Да какие к черту функции? На функциях далеко не уедешь. Используйте возможности CBV и не сношайте себе мозг.
Elaphe
Все, кажется, дошло, буду пробовать. Спасибо.
CBV несколько неудобны для моих целей.
FishHook
Elaphe
CBV несколько неудобны для моих целей.
Это что ж у вас за цели такие?
Elaphe
Бот для telegram. От сервера принимается POST с JSON в теле, на сервер уходит GET с параметрами.
Ради этого импортировать CBV особого смысла не вижу.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB