使用TastyPie将ForeignKey字段更新为null

时间:2012-03-14 04:09:49

标签: python django rest tastypie

是否可以使用TastyPie将ForeignKey字段更新为None

相关问题:tastypie won't remove foreignkey reference during PUT

我有什么:

class SomeObject(models.Model):
    some_field = models.ForeignKey(SomeOtherObject, null=True)

(当然还有相应的TastyPie资源类可以更新其他字段)

我想要的是什么:

使用TastyPie将some_field更新为None

我尝试过的(在JavaScript中):

$.put('/my/api/model/someobject/42/', { some_field: null });
$.put('/my/api/model/someobject/42/', { some_field: '/my/api/model/someotherobject/null/' });
$.put('/my/api/model/someobject/42/', { some_field: '' });
$.put('/my/api/model/someobject/42/', { some_field: 0 });
$.put('/my/api/model/someobject/42/', { some_field: false });

等等。这些都导致404或400.一些导致204,但数据库未更新。

阅读full_dehydrate()中的代码,目前似乎不可能这样做。

我查看了最近的代码on github,我不相信这是可能的。

4 个答案:

答案 0 :(得分:9)

这是一个通用的解决方案。创建基础资源并从此扩展所有其他资源。这是一个黑客,但它的确有效。

class MyResource(ModelResource):
    def obj_update(self, bundle, request=None, **kwargs):
        for field_name in self.fields:
            field = self.fields[field_name]

            if type(field) is ToOneField and field.null and bundle.data[field_name] is None:
                setattr(bundle.obj, field_name, None)

        return super(MyResource, self).obj_update(bundle, **kwargs)

答案 1 :(得分:2)

只需在田间添加水合物方法:

def hydrate_some_field(self, bundle):
    some_object = bundle.obj
    some_other_object = bundle.data['some_field']

    if some_other_object == '':
        some_object.some_field = None
        del bundle.data['some_field']

    return bundle
祝你好运!

答案 2 :(得分:0)

对我来说,亚当托马斯的答案是行不通的。我不得不改变if条件。

所以总代码变为:

def obj_update(self, bundle, request=None, **kwargs):
    super(MyResource, self).obj_update(bundle, **kwargs)
    field_to_update=[]
    for field_name in self.fields:
        field = self.fields[field_name]
        if field.null and (field_name in request.POST):
            if request.POST[field_name] is u'':
                setattr(bundle.obj, field_name, None)
                field_to_update.append(field_name)
    bundle.obj.save(update_fields=field_to_update)
    return bundle

(注意:我使用update_field使sql查询更好:))

(顺便说一句:这也适用于namespacedmodelresources:))

(我无法使用返回超级调用,然后它没有为我保存)

答案 3 :(得分:-1)

试试这个:

$.put('/my/api/model/someobject/42/', { some_field: 'None' }); //DOES NOT WORK

我有一个类似的问题,我试图过滤空外键上的一些对象,并能够通过GET获取它们:

http://localhost:8000/api/v1/page/?format=json&next_page=None

<强>更新

虽然我能够通过传递'None'来获取匹配对象,但它似乎不适用于PUT。我可以通过以下调用将外键字段更新为None:

$.ajax('/api/v1/page/1/',{
    contentType: 'application/json', 
    type: 'put', 
    data: JSON.stringify({"next_page": null})
});

我想通过将null作为application/json传递来解决问题。可能会将空值作为application/x-www-form-urlencoded传递,但我不知道如何。

顺便提一下,application/json是默认情况下编码的tastypie,而application/x-www-form-urlencoded是编码jquery,而其他(所有?)库用于ajax。也许tastypie的默认json编码更容易使用。