嵌套资源,用于tastypie中的多对多关系。父子关系

时间:2016-01-30 18:51:57

标签: django api resources nested tastypie

我有两个资源,客户和电话(我在这里只用了几个字段就这么简单了)。不同的客户可以拥有相同类型的手机。我编写了Modelresource类并通过/ customer /和/ phone /

访问API

现在我想做的是为某个客户取得电话。所以/ customer / 1 / phone /

这些是我的课程的样子。

Models.py

Foo

Api.py

# Defines the phone Model

class Phone(models.Model):
    phone_id= models.AutoField(primary_key=True)
    phone_type = models.CharField(max_length=100)


# Defines the Customer Model

class Customer(models.Model):
    customer_id= models.AutoField(primary_key=True)
    phone = models.ManyToManyField(Phone) 

我调查了http://django-tastypie.readthedocs.org/en/latest/cookbook.html#nested-resources

但它不起作用。我不断收回所有手机,而不仅仅是属于某个客户的手机。因此,如果John有一个android和一个ios,它应该返回两个列表,但如果John有android,它应该只返回android。但这样做,我得到了手机型号的所有手机。

2 个答案:

答案 0 :(得分:1)

型号:

class Phone(models.Model):
    phone_id= models.AutoField(primary_key=True)
    phone_type = models.CharField(max_length=100)


# Defines the Customer Model

class Customer(models.Model):
    customer_id= models.AutoField(primary_key=True)
    phones = models.ManyToManyField(Phone, related_name='customers')

API:

class PhoneResource(ModelResource):
    # TODO: update path
    customers = fields.ManyToManyField('path.to.CustomerResource', "customers")

    class Meta:
        queryset = Phone.objects.all()
        allowed_methods = ['get']
        resource_name = 'phone'

class CustomerResource(ModelResource):
    phones = fields.ManyToManyField(PhoneResource, "phones")

    class Meta:
        queryset = Customer.objects.all()
        allowed_methods = ['get', 'patch', 'put']
        resource_name = 'customer'
        authentication = Authentication()
        authorization = Authorization()

    def prepend_urls(self):
        return [
            url(r'^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/phone%s$' %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('get_customer_phone'), name='customer_phone'),
        ]

    def get_customer_phone(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.")

        phone_resource = PhoneResource()
        return phone_resource.get_list(request, customers=obj.pk)

答案 1 :(得分:0)

你确定你需要单独的prepend_urls吗?您可以为每个客户购买电话列表,将 full = True 添加到ManyToManyField参数:

class CustomerResource(ModelResource):
    phone = fields.ManyToManyField(PhoneResource, "phone", full=True)

    class Meta:
        queryset = Customer.objects.all()
        allowed_methods = ['get', 'patch', 'put']
        resource_name = 'customer'
        authentication = Authentication()
        authorization = Authorization()