2👍
Tastypie doesn’t support deleting objects through a many-to-many relationship. Only update and add are supported. Relevant code. It will call clear on the related manager for your many-to-many field but that will only disassociate your related models from the parent it won’t actually delete them. There was a patch 2 years ago to add the functionality but it wasn’t ever merged.
The best way to handle this is probably to enable filtering on the QuantityResrouce
and PUT
the updated list to the quantity resource filtered by the parent resource which will add/update/delete everything in the collection. Note that you’ll have to add a ForeignKey
field to the QuantityResource
otherwise you won’t be able to save the collection due to database constraints (assuming your entry
field is required on the Quantity
model.
class QuantityResource(ModelResource):
entry = fields.ForeignKey('your.resources.EntryResource', 'entry')
class Meta:
queryset = Quantity.objects.all()
filtering = {
'entry': ['exact'],
}
Here’s a test case to illustrate what I mean:
from tastypie.test import ResourceTestCase
from testres.models import Quantity, Entry
class EntryResourcesTest(ResourceTestCase):
def setUp(self):
super(EntryResourcesTest, self).setUp()
entry = Entry.objects.create(name='Foo')
entry2 = Entry.objects.create(name='Bar')
Quantity.objects.create(entry=entry, quantity=1)
Quantity.objects.create(entry=entry, quantity=3)
Quantity.objects.create(entry=entry, quantity=5)
Quantity.objects.create(entry=entry2, quantity=2)
def test_delete_item(self):
objs = self.deserialize(
self.api_client.get('/api/v1/quantity/?entry=1'))['objects'][1:]
self.assertHttpAccepted(self.api_client.put(
'/api/v1/quantity/?entry=1', data={ 'objects': objs }))
# Ensure resource deleted
obj = self.deserialize(self.api_client.get('/api/v1/entry/1/'))
self.assertEqual(len(obj['quantities']), 2)
# Make sure we didn't delete them all
obj = self.deserialize(self.api_client.get('/api/v1/quantity/'))
self.assertEqual(len(obj['objects']), 3)