【发布时间】: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 的
Authorization和Authentication类进行授权和身份验证。他们应该非常宽容。只是为了检查是否是问题所在。 -
我刚刚将授权和身份验证都更改为完全允许的,但我仍然得到 501 not implemented 错误。