简体   繁体   English

如何通过request.user过滤django-tastypie的ToManyField?

[英]How to filter ToManyField of django-tastypie by request.user?

I'm building an API with tastypie for a django app for data based on the user. 我正在为基于用户的数据的django应用程序构建一个带有密码的API。 The resources are like this: 资源如下:

class PizzaResource(ModelResource):
    toppings = fields.ToManyField(
                'project.app.api.ToppingResource', 
                'topping_set'
            )

    class Meta:
        authentication = SessionAuthentication()
        queryset = Pizza.objects.all()

    def apply_authorization_limits(self, request, object_list):
        return object_list.filter(users=request.user)


class ToppingResource(ModelResource):
    pizza = fields.ForeignKey(PizzaResource, 'pizza')

    class Meta:
        authentication = SessionAuthentication()
        queryset = Topping.objects.filter()

The according models are like this: 相应的模型如下:

class Pizza(model):
    users = ManyToManyField(User)
    toppings = ManyToManyField(Topping)
    # other stuff

class Topping(Model):
    used_by = ManyToManyField(User)
    # other stuff

Now what I want to do is filter the toppings listed with pizza by the Topping.used_by field. 现在我要做的是通过Topping.used_by字段过滤pizza列出的toppings I just found how to filter this field by request unrelated data . 我只是找到了如何通过请求不相关的数据来过滤此字段

How can I filter a relationship field of tastypie by request data? 如何通过请求数据过滤tastypie的关系字段?

Finally I found the answer by stepping through the code of tastypie. 最终,我逐步浏览了密码的代码找到了答案。 It turned out, that the model field in the definition of the ToMany relation ( topping_set here) can be set to a callable. 原来,在该定义的模型场ToMany关系( topping_set这里)可以设置为一个可调用。

Inside the callable you get as only parameter the bundle of data used to dehydrate the resulting data. 在可调用对象内部,您将获得唯一的用于脱水数据结果的数据bundle参数。 Inside this bundle is always the request and so the user instance I want to use to filter. 在此bundle中始终是请求,因此我想使用其进行过滤的user实例。

So what I did was changing this: 所以我所做的就是更改此:

toppings = fields.ToManyField(
    'project.app.api.ToppingResource', 
    'topping_set'
)

to this: 对此:

toppings = fields.ToManyField(
    'project.app.api.ToppingResource', 
    lambda bundle: Topping.objects.filter(
        pizza=bundle.obj, 
        used_by=bundle.request.user
    )
)

and that is it! 就是这样!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM