Using TastyPie to Update ForeignKey Field to Zero

Can I use TastyPie to update a ForeignKey field to None ?

Related question: tastypie will not remove link to foreign link during PUT

What I have:

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

(and, of course, the corresponding TastyPie resource class, which is great for updating other fields)

What I want:

To upgrade some_field to None using TastyPie.

What I tried (in 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 }); 

Etc. All of them result in 404 or 400. Some results are in 204, but the database is not updated.

After reading the code in full_dehydrate() , it seems like this is currently not possible.

I looked at recent code on github and I'm not sure if this is possible.

+6
source share
4 answers

Here is a general solution. Create a base resource and extend all other resources from this. This is a hack, but it works.

 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) 
+9
source

Just add a hydration method for the field:

 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 

Good luck

+2
source

For me, Adam Thomas's answer did not work. I had to change the if condition.

So the general code would be:

 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 

(notice: I used update_field to make the sql query a lot nicer :))

(btw: this also works for namespacedmodelresources :))

(I could not get him to work with a callback super call, then he did not save me)

0
source

Try the following:

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

I had a similar problem when I tried to filter out some objects on a null foreign key and was able to get them using GET:

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

Update:

While I was able to get the corresponding objects, passing "No", it does not work for PUT. I was able to update the foreign key field to None with this call:

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

I assume this reduces the problem by passing null as application/json . You can probably pass null as application/x-www-form-urlencoded , but I don't know how to do this.

By the way, application/json tabs the default encoding, while application/x-www-form-urlencoded is the jquery encoding, and some other (all?) Libraries use for ajax. It may be easier to work with json encoding by default tastypie.

-1
source

Source: https://habr.com/ru/post/910659/


All Articles