我正在使用Tastypie进行POST并创建一个新资源,该工作正常:
class TestResource(ModelResource):
class Meta:
queryset = MemberParticipant.objects.all()
resource_name = 'participant'
allowed_methods = ['post']
def obj_create(self, bundle, request=None, **kwargs):
"""
Creates a new object based on the provided data.
This method overwrites the resource create
as we need to preform extra method calls.
"""
bundle = self.full_hydrate(bundle)
# Check data is valid before trying to create a new resource.
self.is_valid(bundle)
if bundle.errors:
raise ImmediateHttpResponse(response=self.error_response(bundle.request, bundle.errors))
new_user = MemberParticipant.objects.create_user(email=bundle.data['email'],
password=bundle.data['password'])
# Log the user in
email = new_user.email
password = bundle.data['password']
user = authenticate(username=email, password=password)
login(bundle.request, user)
return bundle
然后我在Meta类always_return_data = True
中使用,以便始终在AJAX调用中返回创建的资源。
然而,这样做现在给出了以下错误:
基数为10的int()的文字无效: /django-env/lib/python2.7/site-packages/tastypie/fields.py \“,第234行,在convert \ n return int(value)\ n \ nValueError:int()的基数为10的文字无效: '' \ n“个}
为什么?
完整错误追溯:
{
"error_message": "invalid literal for int() with base 10: ''",
"traceback": "Traceback (most recent call last):
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/resources.py\", line 195, in wrapper
response = callback(request, *args, **kwargs)
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/resources.py\", line 426, in dispatch_list
return self.dispatch('list', request, **kwargs)
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/resources.py\", line 458, in dispatch
response = method(request, **kwargs)
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/resources.py\", line 1326, in post_list
updated_bundle = self.full_dehydrate(updated_bundle)
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/resources.py\", line 832, in full_dehydrate
bundle.data[field_name] = field_object.dehydrate(bundle, for_list=for_list)
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/fields.py\", line 135, in dehydrate
return self.convert(current_object)
File \"/Users/user/Documents/workspace/test/django-env/lib/python2.7/site-packages/tastypie/fields.py\", line 234, in convert
return int(value)
ValueError: invalid literal for int() with base 10: ''"
}
答案 0 :(得分:4)
简而言之,您缺少bundle.obj
并且@mariodev是正确的,如果您只是将create_user()
中的对象分配给此捆绑包对象,它将起作用。但退后一步,有一种更简单的方法。
ModelResource.obj_create()
的目的是创建一个新的模型对象,该对象存储为bundle.obj
,而Tastypie拥有执行此操作的所有代码。您执行的唯一任务是登录新创建的用户。然而,您重写obj_create()
,复制一些Tastypie代码并跳过更多。您检查验证并检查错误,但ModelResource
还将检查授权并保存您未执行的相关模型。 Tastypie也以不同的方式构建bundle.obj
。好吧,特别是你没有构建那个对象,但如果你是它,它只包含电子邮件和密码。如果用户提交了他们的姓名和其他数据怎么办? (当然取决于你的输入代码,但是你在这里创建了一个脆弱的实现假设。)点是,你可以让Tastypie完成所有工作并更简单地注入你的登录逻辑。
class TestResource(ModelResource):
...
def obj_create(self, bundle, **kwargs):
bundle = super(TestResource, self).obj_create(bundle, **kwargs)
user = authenticate(username=bundle.obj.email, password=bundle.obj.password)
if user is not None and user.is_active:
login(bundle.request, user)
return bundle
还有两点:如果您的模型有此字段,也许此时您可以username=bundle.obj.username
。我从Django的文档here中获取了用户/主动检查。
答案 1 :(得分:2)
您需要在bundle.obj
中保存新创建的对象。
答案 2 :(得分:0)
def obj_create(self, bundle, **kwargs):
....
return bundle
默认情况下, bundle
是新创建的对象,包括id
。
“error_message”:“基数为10的int()的文字无效:''”,
id
对象中缺少bundle
时会显示此错误消息。