【问题标题】:Nested Resource for many to many relationship in tastypie. Parent Child relationship美味派中多对多关系的嵌套资源。父子关系
【发布时间】:2016-05-08 10:30:32
【问题描述】:

我有两个资源,客户和电话(我在这里只包含几个字段来简化操作)。不同的客户可以拥有相同类型的电话。我编写了我的 Modelresource 类并通过 /customer/ 和 /phone/ 访问 API

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

这些是我的课程的样子。

模型.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

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

【问题讨论】:

  • customer_phone() 目前是什么样子的?
  • 让它工作的唯一方法是从客户资源中创建一个包,然后删除除电话字段之外的所有字段,然后将其返回。问题在于,我希望 /customer 将电话资源作为 uri 返回,而 /customer/1/phone/ 则返回完整。但我必须要么把两者都装满,要么都装满 uris。
  • 肯定有比这更好的解决方案...

标签: django api resources nested tastypie


【解决方案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)

【讨论】:

  • 我试了一下,我不确定这是否可行。如您所见,客户型号有电话,但电话型号没有客户。那我怎样才能得到这个 customer_set 关系。这是我想不通的最大的事情!我唯一能做的就是 Customer 资源中的 phone = fields.ManyToManyField(PhoneResource, "phone", related_name="phone") 。这是否正确?
  • 是的,好的。我仍然无法为客户取回所有电话。不断返回模型中的所有手机...
  • 我不确定用什么来代替 customer_set。通过查看我的模型和模型资源有什么想法吗?
  • 是的。现在可以了。尽管我不得不将路径作为字符串,因为我遇到了周期性的类导入错误。非常感谢您的帮助 Seàn!
【解决方案2】:

您确定为此需要单独的 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()

【讨论】:

  • 但这也会返回其他字段。我只想拿回手机。因此,如果客户有 first name 和 last name ,那么当我只需要他们的电话时,拨打返回所有字段的电话是没有意义的。这就是为什么我想做一个嵌套的 url /customer/1/phone/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-09-14
  • 2019-01-24
  • 1970-01-01
相关资源
最近更新 更多