Reputation: 141
I have two resources, customer and Phone (I made it simple here by only including few fields). Different customers can have the same type of phone. I wrote my Modelresource class and access the API through /customer/ and /phone/
Now what I want to do is get the phone for a certain customer. so /customer/1/phone/
These are what my classes look like.
# 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)
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
I have looked into http://django-tastypie.readthedocs.org/en/latest/cookbook.html#nested-resources
But it doesn't work. I keep getting all the phones back, not just the phone that belongs to a certain customer. So if John had an android and an ios, it should return both list, but if John had android it should only return android. But doing this I am getting all the phone in the Phone model.
Upvotes: 2
Views: 508
Reputation: 4360
Models:
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)
Upvotes: 1
Reputation: 3363
Are you sure that you need separate prepend_urls for that? You can get phone lists for each customer buy adding full=True to ManyToManyField arguments:
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()
Upvotes: 0