Django的Tastypie许多使用补丁或PUT请求很多(个体经营)领域的更新? [英] Django Tastypie Many to Many (self) field update using a PATCH or PUT request?

查看:181
本文介绍了Django的Tastypie许多使用补丁或PUT请求很多(个体经营)领域的更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的模型:

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:


  1. 水合物usersubs成束(及其嵌套关系 - 从数据库加载,在我们的情况下,空)

  2. 水合物specialUsersub成束(及其嵌套关系 - 包括在请求数据)

  3. 保存specialUsersub(嵌套资源在这里正确保存)

  4. [此时tastypie应检查是否有水合资源被保存,并补充水分束的适当部分,但它没有,所以:]

  5. 保存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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆