tastypie 中多对多关系的嵌套资源。亲子关系

Nested Resource for many to many relationship in tastypie. Parent Child relationship

我有两个资源,customer 和 Phone(我在这里通过只包含几个字段来简化)。不同的客户可以拥有相同类型的phone。我编写了模型资源 class 并通过 /customer/ 和 /phone/

访问了 API

现在我要做的是为某个客户获取phone。所以 /customer/1/phone/

这些是我的 class 的样子。

Models.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) 

Api.py

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

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

    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 customer_phone(self, request, **kwargs):
        # My Question is what goes in this function 
        # I want to get only the phones for the given customer, and exclude other phones that does not belong to them

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

但是没用。我一直在取回所有 phone,而不仅仅是属于某个客户的 phone。所以如果 John 有一个 android 和一个 ios,它应该 return 都列出,但是如果 John 有 android 它应该只 return android .但是这样做我得到了 Phone 模型中的所有 phone 。

您确定需要单独的 prepend_urls 吗?您可以获得每个客户购买的 phone 列表,将 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()

型号:

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)