2012-02-20 1 views
1

У меня есть два ModelResource s, Attack и Packet, связанные с ManyToManyField.Вложенные ToManyFields в django-tastypie

Это, как правило, показывает Packet.attacks, содержащий 1-3 атак, и Attack.packets, содержащий сотни пакетов.

Путь я планировал сделать это так: каждый AttackResource имеет Attack.packets атрибут, который является ссылкой на в QuerySet, содержащей Attack.packets и где QuerySet вложен в 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 находится в пакетах.

Моего 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

Вы можете создавать вложенные ресурсы путем переопределения функции override_urls в ваших ресурсах. Один из способов сделать это можно найти в tastypie documentation. Он основан на создании пользовательской функции в вашем ресурсе, которая будет получать всех детей, и вам нужно написать это для каждого ресурса.

Если это не подходит для вас, то есть другой способ сделать это. Более общий способ и он будет работать для всех вложенных ресурсов без написания каких-либо дополнительных функций. Его можно найти на этом gist.

+0

Я пытался сделать это с поваренной и теперь с сутью. Я в недоумении. Обновление вопроса с дополнительной информацией. – rouge8

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)