【问题标题】:tastypie posting and full example美味的张贴和完整的例子
【发布时间】:2012-02-25 23:30:54
【问题描述】:

是否有完整的 sweetpie django 示例站点和设置可供下载?我整天都在努力把头缠在上面。我有以下代码。基本上,我有一个用 ajax 处理的 POST 表单。当我在表单上单击“提交”并运行 ajax 请求时,调用返回“POST http://192.168.1.110:8000/api/private/client_basic_info/ 404 (NOT FOUND)”我认为 URL 配置正确。我可以访问http://192.168.1.110:8000/api/private/client_basic_info/?format=json 就好了。我是否遗漏了一些设置或在我的方法中犯了一些基本错误?我的意图是每个用户可以填写/修改一个且只有一个“客户基本信息”表格/模型。

一个页面:

{% extends "layout-column-100.html" %}
{% load uni_form_tags sekizai_tags %}

{% block title %}Basic Information{% endblock %}

{% block main_content %}

    {% addtoblock "js" %}
        <script language="JavaScript">

        $(document).ready( function() {

            $('#client_basic_info_form').submit(function (e) {

                form = $(this)

                form.find('span.error-message, span.success-message').remove()
                form.find('.invalid').removeClass('invalid')
                form.find('input[type="submit"]').attr('disabled', 'disabled')

                e.preventDefault();
                var values = {}

                $.each($(this).serializeArray(), function(i, field) {
                    values[field.name] = field.value;
                })


                $.ajax({
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify(values),
                    dataType: 'json',
                    processData: false,
                    url: '/api/private/client_basic_info/',
                    success: function(data, status, jqXHR) {
                        form.find('input[type="submit"]')
                            .after('<span class="success-message">Saved successfully!</span>')
                            .removeAttr('disabled')
                    },
                    error: function(jqXHR, textStatus, errorThrown) {

                        console.log(jqXHR)
                        console.log(textStatus)
                        console.log(errorThrown)

                        var errors = JSON.parse(jqXHR.responseText)
                        for (field in errors) {
                            var field_error = errors[field][0]
                            $('#id_' + field).addClass('invalid')
                                .after('<span class="error-message">'+ field_error +'</span>')
                        } 
                        form.find('input[type="submit"]').removeAttr('disabled')
                    }
                }) // end $.ajax()

            }) // end $('#client_basic_info_form').submit()

        }) // end $(document).ready()

        </script>
    {% endaddtoblock %}


{% uni_form form form.helper %}


{% endblock %}

资源

from residence.models import ClientBasicInfo
from residence.forms.profiler import ClientBasicInfoForm

from tastypie import fields
from tastypie.resources import ModelResource
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import DjangoAuthorization, Authorization
from tastypie.validation import FormValidation
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User

class UserResource(ModelResource):

    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
        fields = ['username']
        filtering = {
            'username': ALL,
        }
        include_resource_uri = False
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

    def dehydrate(self, bundle):
        forms_incomplete = []

        if ClientBasicInfo.objects.filter(user=bundle.request.user).count() < 1:
            forms_incomplete.append({'name': 'Basic Information', 'url': reverse('client_basic_info')})

        bundle.data['forms_incomplete'] = forms_incomplete
        return bundle


class ClientBasicInfoResource(ModelResource):
    user = fields.ForeignKey(UserResource, 'user')


    class Meta:
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()
        include_resource_uri = False
        queryset = ClientBasicInfo.objects.all()
        resource_name = 'client_basic_info'
        validation = FormValidation(form_class=ClientBasicInfoForm)
        list_allowed_methods = ['get', 'post', ]
        detail_allowed_methods = ['get', 'post', 'put', 'delete']

编辑:

我的资源文件现在是:

from residence.models import ClientBasicInfo
from residence.forms.profiler import ClientBasicInfoForm

from tastypie import fields
from tastypie.resources import ModelResource
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import DjangoAuthorization, Authorization
from tastypie.validation import FormValidation
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User

class UserResource(ModelResource):

    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
        fields = ['username']
        filtering = {
            'username': ALL,
        }
        include_resource_uri = False
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

    #def apply_authorization_limits(self, request, object_list):
    #    return object_list.filter(username=request.user)

    def dehydrate(self, bundle):
        forms_incomplete = []

        if ClientBasicInfo.objects.filter(user=bundle.request.user).count() < 1:
            forms_incomplete.append({'name': 'Basic Information', 'url': reverse('client_basic_info')})

        bundle.data['forms_incomplete'] = forms_incomplete
        return bundle


class ClientBasicInfoResource(ModelResource):
    # user = fields.ForeignKey(UserResource, 'user')

    class Meta:
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()
        include_resource_uri = False
        queryset = ClientBasicInfo.objects.all()
        resource_name = 'client_basic_info'
        validation = FormValidation(form_class=ClientBasicInfoForm)
        #list_allowed_methods = ['get', 'post', ]
        #detail_allowed_methods = ['get', 'post', 'put', 'delete']

    def apply_authorization_limits(self, request, object_list):
        return object_list.filter(user=request.user)

我将 ClientBasicInfo 的用户字段设为可为空,并且 POST 似乎可以正常工作。我现在想尝试更新条目。那只是将pk附加到ajax url吗?例如 /api/private/client_basic_info/21/?当我提交该表单时,我收到一条 501 NOT IMPLEMENTED 消息。我究竟没有实施什么?我正在继承 ModelResource,它应该根据文档实现所有与 ORM 相关的功能。

【问题讨论】:

  • APPEND_SLASHES 可能有问题?您是否尝试过发帖到192.168.1.110:8000/api/private/client_basic_info(不带斜杠)?只是猜测。
  • 嗯,我去掉了 url 的斜线,得到“你通过 POST 调用了这个 URL,但是 URL 没有以斜线结尾,并且你设置了 APPEND_SLASH。”我将 APPEND_SLASH = False 应用于我的设置,现在我收到一条 403 Forbidden 消息(CSRF 验证失败)。我通过使视图 csrf_exempt 克服了这一点。现在我得到一个 501 未实现的错误。我添加了一个自定义水合物功能并通过了它。我尝试提交一个表单来更新对象,但我收到另一个错误。一个又一个的错误,我想我会放弃seatpiepie。
  • 我不是 TastyPie 专家,所以只能做出更多猜测。您是否尝试过使用不同的身份验证和授权后端?尝试分别使用tastepie 的AuthorizationAuthentication 类进行授权和身份验证。他们应该非常宽容。只是为了检查是否是问题所在。
  • 我刚刚将授权和身份验证都更改为完全允许的,但我仍然得到 501 not implemented 错误。

标签: django api tastypie


【解决方案1】:

好的,我想通了。我没有小心。 AJAX 请求类型应该是“PUT”来处理 501 未实现错误(我正在执行更新)。我还设置了一个自定义身份验证类来处理 403 错误。

【讨论】:

    猜你喜欢
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多