Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Собственные (не основанные на CBV) классы для вьюх [RSS Feed]

#1 Дек. 9, 2016 13:26:48

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Пишу вьюху, которая представляет собой один класс, в нем несколько методов.
Некоторые методы принимают поступивший 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) буду весьма благодарна.

Отредактировано Elaphe (Дек. 9, 2016 13:45:19)

Офлайн

#2 Дек. 9, 2016 13:54:02

scidam
Зарегистрирован: 2016-06-15
Сообщения: 288
Репутация: +  35  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх


 #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)
]

Офлайн

#3 Дек. 9, 2016 14:19:34

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

А как тогда ссылаться на другие методы внутри CoolClass? Не оборачивать же все в staticmethod

Офлайн

#4 Дек. 9, 2016 14:54:22

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

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 и работаеют методы объекта.



Отредактировано FishHook (Дек. 9, 2016 14:55:51)

Офлайн

#5 Дек. 9, 2016 15:06:25

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Разве это не касается только CBV?
Кроме того, как быть, если класс должен обеспечивать несколько представлений?
Или проще не сношать себе мозг и оставить все в виде функций?

Отредактировано Elaphe (Дек. 9, 2016 15:17:46)

Офлайн

#6 Дек. 9, 2016 15:22:22

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Elaphe
Разве это не касается только CBV
CBV - это представления основанные на классах. Какая разница, какой это класс: из состава джанги или ваш собственный. В любом случае в урл-паттерне должна быть функция (это API джанги), и даже в случае представленя-класса это должна быть функция. И где её взять? Только сделав один из методов класса статическим (точнее методом класса). Чем вам не нравится встроенная реализация? Возьмите базовый класс View и наворачивайте его как вам угодно. По-другому всё равно вряд ли получится. Можно, конечно, попробовать сделать синглтоны, но это приведет к возможности хранить состояние объекта между сессиями, то есть в продакшене при нескольких запущенных процессах вы получите непредсказуемое поведение.



Офлайн

#7 Дек. 9, 2016 15:24:56

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Elaphe
Кроме того, как быть, если класс должен обеспечивать несколько представлений?
Вас никто не принуждает вызывать именно as_view(). Наделайте as_view1(), as_view2() и т.д. Но зачем?
Elaphe
Или проще не сношать себе мозг и оставить все в виде функций?
Да какие к черту функции? На функциях далеко не уедешь. Используйте возможности CBV и не сношайте себе мозг.



Офлайн

#8 Дек. 9, 2016 15:28:30

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Все, кажется, дошло, буду пробовать. Спасибо.
CBV несколько неудобны для моих целей.

Офлайн

#9 Дек. 9, 2016 15:36:35

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Elaphe
CBV несколько неудобны для моих целей.
Это что ж у вас за цели такие?



Офлайн

#10 Дек. 12, 2016 09:01:32

Elaphe
Зарегистрирован: 2015-02-04
Сообщения: 125
Репутация: +  5  -
Профиль   Отправить e-mail  

Собственные (не основанные на CBV) классы для вьюх

Бот для telegram. От сервера принимается POST с JSON в теле, на сервер уходит GET с параметрами.
Ради этого импортировать CBV особого смысла не вижу.

Офлайн

  • Начало
  • » Django
  • » Собственные (не основанные на CBV) классы для вьюх[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version