我有两个ModelResource
,Attack
和Packet
,与ManyToManyField相关。
这往往会显示Packet.attacks
包含1-3次攻击,Attack.packets
包含数百个数据包。
我计划这样做的方式是:每个AttackResource
都有一个Attack.packets
属性,该属性是包含Attack.packets
的查询集的链接,以及查询集嵌套的位置在AttackResource
。
即:
/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's gist拥有嵌套资源,但转到/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,
}
答案 0 :(得分: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)
答案 1 :(得分:0)
您可以通过覆盖资源中的override_urls函数来创建嵌套资源。 一种方法可以在tastypie documentation中找到。它基于在您的资源中创建一个将获得所有子项的自定义函数,并且您需要为每个资源编写此函数。
如果这对您来说效果不好,那么还有其他方法可以做到这一点。更通用的方法,它适用于所有嵌套资源,无需编写任何其他功能。它可以在gist上找到。