LINUX.ORG.RU

Django tastypie & Backbone.js - 501 NOT IMPLEMENTED !

 , , , ,


0

1

Всем доброго времени суток!

Я еще падаван в разработке клиентской части. Пилю web-приложение на django + backbone. В качестве серверной реализации RESTful API использую django-tastypie, а на клиенете - backbone.js.

Все бы хорошо, да только при попытке апдейтить существующую модель - получаю ошибку 501 NOT IMPLEMENTED! Google ничего вятного по данному поводу не дает. Может подскажет достопочтеннейшая публика ЧЯДНТ?

models.py

class Project(models.Model):
    name = models.CharField(u"Название проекта", max_length=32, unique=True)
    description = models.TextField(
        u"Описание проекта", validators=[MaxLengthValidator(256)],
        help_text=u"Краткое описание проекта", blank=True
    )
    user = models.ForeignKey(User, verbose_name=u"Пользователь")

    ...

resources.py

class UserResources(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = "users_list"
        list_allowed_methods = ['get']
        filtering = {
            "id": ALL,
        }
        authorization = Authorization()
        always_return_data = True


class ProjectsResource(ModelResource):
    user = fields.ForeignKey(UserResources, 'user', full=True)

    class Meta:
        queryset = Project.objects.all()
        list_allowed_methods = ['get', 'post']
        detail_allowed_methods = ['get', 'post', 'put', 'patch', 'delete']
        resource_name = 'projects_list'
        filtering = {
            'id': ALL,
            'user': ALL
        }
        authorization = Authorization()
        always_return_data = True

template:

<!-- CREATE AND EDIT TEMPLATES -->
  <script type="text/template" id="create-project-template">
    <form class="form-group create-project-form">
      <label for="name">Название проекта</label>
      <input type="text" name="name" id="name" class="form-control" value="<%= project ? project.get('name') : '' %>" />
      <br>
      <label for="description">Описание проекта</label>
      <textarea name="description" id="description" class="form-control">
        <%= project ? project.get('description') : '' %>
      </textarea>
      <% if(project) { %>
        <input type="hidden" name="id" value="<%= project ? project.get('id') : '' %>" />
      <% }; %>
      <br>
      <button type="submit" class="btn btn-success">
        <span class="glyphicon glyphicon-ok"></span>&nbsp;<%= project ? 'Отредактировать' : 'Сохранить' %>
      </button>
      <a class="btn btn-danger" href="#projects">
        <span class="glyphicon glyphicon-remove"></span>&nbsp;Отмена
      </a>
    </form>
  </script>

app.js:

/* CREATE AND EDIT PROJECT VIEW */
var EditProjectView = Backbone.View.extend({
    el: "#main-container",
    events: {
        "submit .create-project-form":  "createProject"
    },

    render: function (options) {
        if (options.project_id) {
            var project = new ProjectModel({id: options.project_id});
            var _self = this;
            project.fetch({
                success: function(project) {
                    var template = _.template( $("#create-project-template").html(), {project: project} );
                    _self.$el.html(template);
                }
            });
        }
        else {
            var template = _.template( $("#create-project-template").html(), {project: null} );
            this.$el.html(template);
        }
    },
    createProject: function(event) {
        var projectDetail = $(event.currentTarget).serializeObject();
        var project = new ProjectModel();

        project.save(projectDetail, {
            patch: true,
            success: function() {
                router.navigate("projects", {trigger: true});
            },
            error: function() {
                console.log("FUCK!");
            }
        });
        return false;
    }
});

Нахрена при создании указывать метод PATCH? Оно должно быть POST.

heilkitty ★★ ()
Ответ на: комментарий от heilkitty

Вы правы. При создании новой записи болжен быть разрешен POST, а при изменении уже существующей записи - PUT. Исправил, но проблема осталась(.

KernelPanic ()

Надо ещё URL посмотреть, куда модель ломится при sync. Код ProjectModel в студию.

heilkitty ★★ ()
Ответ на: комментарий от KernelPanic

Короче, надо убедиться, что urlRoot тот же самый, что и у tastypie ресурса. Я с tastypie давно уже не работал, но, похоже, у ProjectsResource адрес будет /api/projects_list/ или /api/v1/projects_list/. Надо его точно узнать и впейсать в urlRoot.

heilkitty ★★ ()
Ответ на: комментарий от heilkitty

Убедился. Урл'ы у ресурса и модели совпадают. Сдается мне, что это tastypie на что-то матерится. Вот только на что?

KernelPanic ()

Проблема разрешается указанием конкретного типа HTTP запроса. При апдейте _уже существующей модели_ (у которой уже есть id) в методе save() добавляем type: «PUT».

В итоге, метод createProject, вьюхи EditProjectView, будет выглядеть следующим образом:

createProject: function(event) {
        var projectDetail = $(event.currentTarget).serializeObject();
        var project = new ProjectModel();
        project.save(projectDetail, {
            type: 'PUT',
            success: function() {
                router.navigate("projects", {trigger: true});
            },
            error: function() {
                console.log("FUCK!");
            }
        });
        return false;
    }

KernelPanic ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.