1

我有两个ModelResourcesAttackPacket,由 ManyToManyField 关联。

这往往表现为Packet.attacks包含 1-3 次攻击,并Attack.packets包含数百个数据包。

我一直计划这样做的方式是:每个AttackResource都有一个Attack.packets属性,该属性是指向包含查询集的链接,Attack.packets并且查询集嵌套在AttackResource.

IE:

/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

我怎样才能做到这一点?

我试过按照cyberdelia的要点来嵌套资源,但/api/attack/1/packets/实际上并不包含attack.id在packet.attacks中的数据包。

我的ModelResource课程与要点相同,然后我的其他资源是:

class AttackResource(ModelResource):
    packets = fields.ToManyField('honeywall.api.PacketResource', 'packets', 'attack')

    class Meta:
        queryset = Attack.objects.all()
        resource_name = 'attack'

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,
        }
4

2 回答 2

1

将此添加到您的 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)
于 2013-09-19T19:42:04.763 回答
0

您可以通过覆盖资源中的 override_urls 函数来创建嵌套资源。一种方法可以在tastepie文档中找到。它基于在您的资源中创建一个自定义函数,该函数将获取所有子项,您需要为每个资源编写此函数。

如果这对您不起作用,那么还有其他方法可以做到这一点。一种更通用的方法,它将适用于所有嵌套资源,而无需编写任何额外的函数。它可以在这个要点上找到。

于 2012-02-20T07:45:04.650 回答