2016-01-30 3 views
2

У меня есть два ресурса, клиент и телефон (я сделал это просто здесь, только включая несколько полей). У разных клиентов может быть один и тот же тип телефона. Я написал свой класс Modelresource и получил доступ к API через/customer/and/phone/Вложенный ресурс для многих-многих отношений в tastypie. Родительские отношения с ребенком

Теперь, что я хочу сделать, это получить телефон для определенного клиента. so/customer/1/phone/

Это то, на что похожи мои классы.

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

Но это не работает. Я все время возвращаю все телефоны, а не только тот, который принадлежит определенному клиенту. Поэтому, если у Джона был андроид и ios, он должен вернуть оба списка, но если у Джона был андроид, он должен только вернуть андроид. Но делая это, я получаю весь телефон в модели телефона.

+0

Что 'customer_phone()' в настоящее время выглядят? –

+0

Единственный способ заставить его работать, это создать пакет из ресурса клиента, а затем удалить все поля, кроме поля телефона, а затем вернуть его. Проблема с этим заключается в том, что я хочу/клиент вернуть ресурс телефона, как uri, и/customer/1/phone /, чтобы вернуться полностью. Но я должен либо получить как полный, либо оба, как ури. – Purpamine

+0

Должно быть лучшее решение, чем это ... – Purpamine

ответ

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) 
+0

Я дал это, и я не уверен, что это может сработать. Как вы можете видеть, у модели клиента есть телефон, но у модели телефона нет клиента. Тогда как я могу получить это отношение customer_set. Это самая большая вещь, которую я не могу понять! Единственное, что я могу сделать, это phone = fields.ManyToManyField (PhoneResource, «phone», related_name = «phone») в ресурсе Customer. Это даже правильно? – Purpamine

+0

Django автоматически добавляет обратное отношение: https://docs.djangoproject.com/en/1.9/ref/models/relations/ https://docs.djangoproject.com/es/1.9/topics/db/queries/ # lookups-that-span-relationship –

+0

Да, хорошо. Я все еще не могу вернуть все телефоны для клиента. Продолжает возвращать все телефоны в модели ... – Purpamine

0

Вы уверены, что для этого вам нужны отдельные prepend_urls? Вы можете получить список телефонов для каждого покупки клиента, добавив полный = 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() 
+0

Но это также вернет другие поля. Я хочу только вернуть телефоны. Поэтому, если у клиента есть имя и фамилия, не имеет смысла делать вызов, который возвращает все поля, когда мне нужен только их телефон. Вот почему я хотел сделать вложенный url/customer/1/phone/ – Purpamine