Reputation: 463
I have two ModelResource
s, Attack
and Packet
, related by a ManyToManyField.
This tends to show up with Packet.attacks
containing 1-3 attacks, and Attack.packets
containing hundreds of packets.
The way I've been planning to do this is this: each AttackResource
has an Attack.packets
attribute that is a link to a the queryset containing Attack.packets
and where the queryset is nested in AttackResource
.
i.e.:
/api/attack/1/ # contains attribute with URL of /api/attack/1/packets/
/api/attack/1/packets/ # contains all packets where attack with id=1 is in Packet.attacks
How can I do this?
I've tried following cyberdelia's gist to have nested resources, but going to /api/attack/1/packets/
doesn't actually contain packets where attack.id is in packet.attacks.
My ModelResource
class is identical to the gist, and then my other resources are:
class AttackResource(ModelResource):
packets = fields.ToManyField('honeywall.api.PacketResource', 'packets', 'attack')
class Meta:
queryset = Attack.objects.all()
resource_name = 'attack'
and
class PacketResource(ModelResource):
attacks = fields.ToManyField('honeywall.api.AttackResource', 'attacks', 'packet')
class Meta:
queryset = Packet.objects.all()
resource_name = 'packet'
filtering = {
'attacks': ALL_WITH_RELATIONS,
}
Upvotes: 1
Views: 1344
Reputation: 3501
Add this to your AttackResource:
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/packets%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_attacks'), name="api_get_attacks"),
]
def get_attacks(self, request, **kwargs):
try:
bundle = self.build_bundle(data={'pk': kwargs['pk']}, request=request)
obj = self.cached_obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs))
except ObjectDoesNotExist:
return HttpGone()
except MultipleObjectsReturned:
return HttpMultipleChoices("More than one resource is found at this URI.")
attack_resource = AttackResource()
return attack_resource.get_detail(request, id=obj.pk)
Upvotes: 1
Reputation: 17621
You can create nested resources by overriding a override_urls function in your resources. One way to do this can be found in tastypie documentation. It`s based on creation of a custom function in your resource that will get all children, and you need to write this for every resource.
If this is not work well for you then there other way to do it.A more generic way and it will work for all nested resources without writing any additional functions. It can be found on this gist.
Upvotes: 0