Django的Tastypie许多使用补丁或PUT请求很多(个体经营)领域的更新? [英] Django Tastypie Many to Many (self) field update using a PATCH or PUT request?
问题描述
我有这样的模型:
class UserSub(models.Model):
user = models.OneToOneField(User, related_name='userSub')
amigos = models.ManyToManyField('self', null=True)
title = models.TextField()
进口Django的用户模型。
Imported Django User Model.
和以下资源:
class UserResource(ModelResource):
usersub = fields.OneToOneField('test.api.UserSubResource', attribute = 'personal', related_name='user', full=True, null=True)
class Meta:
object_class = User
fields = ['username', 'first_name', 'last_name', 'password', 'email']
detail_allowed_methods = ['get', 'post', 'put']
authentication = Authentication()
authorization = Authorization()
queryset = User.objects.all()
resource_name = 'users'
excludes = ['id']
class UserSubResource(ModelResource):
user = fields.OneToOneField('test.api.UserResource', attribute = 'user', related_name = 'userSub')
amigos= fields.ToManyField('test.api.UserSubResource', attribute = 'amigos', null=True)
class Meta:
object_class = UserSub
fields = ['title']
detail_allowed_methods = ['get', 'post', 'put', 'patch']
authentication = Authentication()
authorization = Authorization()
always_return_data = True
queryset = UserSub.objects.all()
resource_name = 'usersub'
excludes = ['id']
我想吾友特定用户的值更新。我的数据是:
I am trying to update amigos values for a specific user. My data is:
usersub_json: {"amigos":["/api/v1/usersub/9/","/api/v1/usersub/8/"]}
$.ajax({
url : 'http://127.0.0.1:8000' + usersub_uri,
type : 'PUT',
contentType : 'application/json',
data : usersub_json,
dataType : 'json',
processData : false,
error : function(http) {
if (http.responseText != "") {
alert(http.responseText);
}
}
})
我收到 202接受从PUT请求,并且不更新吾友。
I am getting "202 ACCEPTED" from PUT request, and the amigos are not updated.
和 202接受从PATCH请求,并且不更新吾友。
And "202 ACCEPTED" from PATCH request, and the amigos are not updated.
如果我创建USERSUB时,在第一篇文章的请求添加吾友,这将它们添加到数据库中成功。但是,如果我用PUT或PATCH添加更多的阵列不更新。
If I add the amigos in the first post request when creating a usersub, it adds them to the database successfully. But doesn't update if I add more to the array using PUT or PATCH.
推荐答案
我不能肯定它是与您的情况,但我发现我的问题。
I can't be sure it's the same as your situation, but I found my problem.
让我修改的例子稍微反映我遇到的情况:
Let me modify your example slightly to reflect the situation I encountered:
class UserResource(ModelResource):
usersubs = fields.ToManyField('test.api.UserSubResource', attribute = 'usersubs', full=True, null=True)
specialUsersub = fields.ToOneField('test.api.UserSubResource', attribute = 'special_user_sub', full=True, null=True)
class Meta:
object_class = User
fields = ['username', 'first_name', 'last_name', 'password', 'email']
detail_allowed_methods = ['get', 'post', 'put']
authentication = Authentication()
authorization = Authorization()
queryset = User.objects.all()
resource_name = 'users'
excludes = ['id']
class UserSubResource(ModelResource):
amigos= fields.ToManyField('test.api.UserSubResource', attribute = 'amigos', null=True)
class Meta:
object_class = UserSub
fields = ['title']
detail_allowed_methods = ['get', 'post', 'put', 'patch']
authentication = Authentication()
authorization = Authorization()
always_return_data = True
queryset = UserSub.objects.all()
resource_name = 'usersub'
excludes = ['id']
和要求:
PATCH /users/1/
{ "specialusersub" : { "id" : 3, "amigos" : ["/api/v1/usersub/9/","/api/v1/usersub/8/"] } }
在我的情况下,这个问题是由试图修补嵌套深两个层次,当父资源在顶层的ToMany关系还存在着一个ToMany资源引起的。因为因为在资源字段的顺序嵌套的,操作的顺序发生是这样的:
In my case this problem was caused by trying to patch a ToMany resource nested two levels deep when the parent resource also existed in a ToMany relationship at the top level. Because of the nesting and because of the order of fields on the resource, the order of operations happened like this:
- 水合物usersubs成束(及其嵌套关系 - 从数据库加载,在我们的情况下,空)
- 水合物specialUsersub成束(及其嵌套关系 - 包括在请求数据)
- 保存specialUsersub(嵌套资源在这里正确保存)
- [此时tastypie应检查是否有水合资源被保存,并补充水分束的适当部分,但它没有,所以:]
- 保存usersubs(如果specialUsersub资源也存在于usersubs当时被previously保存将在usersubs步骤水合已加载的陈旧数据被覆盖1)
要更precise,因为tastypie用什么存放在包再植他们面前故意清除所有M2M关系,陈旧的数据则会覆盖新的数据,在3中创建的吾友被删除,并用[]替换为空那是在1加载列表。
To be more precise, because tastypie deliberately clears all m2m relationships before repopulating them with what's stored in the bundle, the stale data clobbers the new data, the amigos created in 3 are deleted and replaced with the [] empty list that was loaded in 1.
我还在测试,但我认为解决方案/黑客是确保你包括更新的嵌套资源的等。无论您tastypie资源可能期待它:
I'm still testing, but I think the solution/hack is to ensure that you include the updated nested resource whereever your tastypie resource might be expecting it:
PATCH /users/1/
{ "usersubs" : [{ "id" : 3, "amigos" : ["/api/v1/usersub/9/","/api/v1/usersub/8/"] }], "specialusersub" : { "id" : 3, "amigos" : ["/api/v1/usersub/9/","/api/v1/usersub/8/"] } }
显然,这并不理想。我会让你知道,如果我拿出一个更合适的解决方案。
Obviously that's not ideal. I'll let you know if I come up with a more appropriate solution.
这篇关于Django的Tastypie许多使用补丁或PUT请求很多(个体经营)领域的更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!