Классы Restful Handler Tornado

Я прочитал и нашел этот ответ на вопрос о проблеме, связанной с этим, но я действительно хочу знать, как реализовать эту структуру и сколько классов обработчиков мне нужно:

1  GET    /items        #=> index
2  GET    /items/1      #=> show
3  GET    /items/new    #=> new
4  GET    /items/1/edit #=> edit
5  PUT    /items/1      #=> update
6  POST   /items        #=> create
7  DELETE /items/1      #=> destroy

Я думал, что 2,5,7 сопоставлены с одним обработчиком, перенаправленным на /items/[0-9]+, и иметь 3 новых обработчика для элементов, items/new и /items/[0-9]+/edit. Недостатком является то, что было неоптимальным решением иметь 4 обработчика для одного ресурса.

Я ужасно новичок в правильной маршрутизации/обработке/веб-приложениях, но я, по крайней мере, хорошо читаю, прежде чем начать что-то делать. Есть ли какие-нибудь лучшие предложения о том, сколько/как вы маршрутизируете свои обработчики?


person odgrim    schedule 18.11.2011    source источник
comment
Не могли бы вы исключить пункт 3 и использовать вместо него пункт 6? Или вы специально хотите /items/new?   -  person aychedee    schedule 12.09.2012


Ответы (1)


Ну, это во многом стилистически. Каждый обработчик запросов в этой ситуации представляет собой удаление оператора if из одного из ваших методов. Я думаю, что может быть понятнее ограничить количество RequestHandlers. Наилучшие результаты, я думаю, могут быть достигнуты с одним обработчиком и тремя маршрутами.

Я также выбросил ваш элемент 3. Поскольку он является дубликатом элемента 6. Если наличие URL-адреса «элементы/новый» действительно важно, мы могли бы вернуть его. Хотя я думаю, что в этот момент вам понадобится другой обработчик. класс для наглядности.

class ItemHandler(tornado.web.RequestHandler):

    def get(self, item_id=None, edit=False):
        if item_id:
            # get item from db
            if edit:
                new_data_from_query_string = self.get_argument('item_data')
                # do edit, save item
            # return item
        else:
            # return index

    def put(self, item_id):
        data = self.get_argument('item_data')
        # do your update for item

    def post(self):
        data = self.get_argument('item_data')
        # do your item creation

    def delete(self, item_id):
        # do your deletion for item_id

Тогда фактическое приложение может быть создано следующим образом:

tornado.web.application([
    (r'/items$', ItemHandler),
    (r'/items/(\d+$)', ItemHandler),
    (r'/items/(\d+)/(edit)$', ItemHandler),
])

Если вам нужен URL-адрес «/items/new», я бы, вероятно, предложил поместить его в отдельный обработчик, потому что в противном случае это сделало бы логику чрезмерно сложной.

person aychedee    schedule 12.09.2012
comment
Get of items/new представляет собой форму для создания нового элемента. В любом случае, это решение, которое я выбрал год назад! - person odgrim; 08.02.2013
comment
Ха! Спасибо, что вернулись и поставили галочку тогда. Рад, что смог помочь. - person aychedee; 08.02.2013
comment
@aychedee Глядя на код вашего обработчика, не должны ли ваши маршруты следовать этому шаблону именования групп: (r'/items/(?P<item_id>\d+$)', ItemHandler). Это, вероятно, делает ваш пример более полным. - person Ethan; 15.03.2015
comment
по поводу пункта 3. Я бы не советовал делать write request по методу GET. Методы GET предназначены для read requests. Он не должен создавать/обновлять. - person SanD; 29.11.2016
comment
Хотя я согласен с вами, я (четыре года назад) отвечал на вопрос о том, как сделать что-то, что явно имеет метод GET с конечной точкой редактирования. - person aychedee; 30.11.2016