[Answered ]-How do I Delete related resources with TastyPie

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)
👤mcrute

Leave a comment