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)
我有两个资源,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)