我有这个型号:
class UserSub(models.Model):
user = models.OneToOneField(User, related_name='userSub')
amigos = models.ManyToManyField('self', null=True)
title = models.TextField()
导入的Django用户模型。
以下资源:
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']
我正在尝试更新特定用户的amigos值。我的数据是:
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);
}
}
})
我从PUT请求中收到“ 202 ACCEPTED ”,并且没有更新amigos。
来自PATCH请求的“ 202 ACCEPTED ”,并且amigos不会更新。
如果我在创建usersub时在第一个post请求中添加了amigos,它会成功地将它们添加到数据库中。但是如果我使用PUT或PATCH向阵列添加更多内容,则不会更新。
答案 0 :(得分:2)
我不能确定它和你的情况一样,但我发现了我的问题。
让我稍微修改你的例子以反映我遇到的情况:
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资源。由于嵌套以及资源上字段的顺序,操作顺序如下:
更确切地说,因为tastypie故意清除所有m2m关系,然后用存储在bundle中的内容重新填充它们,过时的数据会破坏新数据,3中创建的amigos被删除并替换为[]空列表。装入1。
我还在测试,但我认为解决方案/黑客是确保您包含更新的嵌套资源 whereever 您的tastypie资源可能期望它:
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/"] } }
显然这并不理想。如果我想出一个更合适的解决方案,我会告诉你的。