Django:过滤请求结果仅包含与请求用户相关的数据

时间:2015-10-15 14:50:52

标签: python django rest request sails.js

我是Django的初学者(虽然我有使用Sails.js + Angular进行网页开发的经验)所以请耐心等待。

我有一个现有的应用程序,它在Sails.js后端和AngularJS前端之间进行通信时使用REST API。现在,我们发现后端不适合我们的目的,我们将在不久的将来交换使用Django。 Sails.js会自动为控制器创建REST方法,而Django却没有,所以我想我将使用像Django Rest Framework这样的东西来创建API。

所以是的,我发现大多数事情都有相应的功能。我尚未找到的东西是Sails.js功能的替代品,称为“策略”。它们是可以对某些控制器操作的查询执行的函数,可以定义为特定于模型,特定于模型控制器操作和特定于请求类型。例如,您可以使用“$array = array( 'bla1' = array( 'subbla1' => 'subval1', 'subbla2' => 'subval2', 'subbla3' => 'subval3', 'subbla4' => 'subval4' ), 'bla2' = array( 'subbla1' => 'subval1', 'subbla2' => 'subval2', 'subbla3' => 'subval3', 'subbla4' => 'subval4' ), 'bla3' = array( 'subbla1' => 'subval1', 'subbla2' => 'subval2', 'subbla3' => 'subval3', 'subbla4' => 'subval4' ), ); foreach ($array as $key => $value) { foreach ($value as $subkey => $subvalue) { // here you have $key, $value, $subkey and $subvalue at your disposal. } } ”策略检查请求的用户是否已通过身份验证,并在执行实际请求的控制器方法之前执行策略。您还可以使用这些来修改请求对象,然后再将它们传递给控制器​​。现在我的实际问题是:

假设我有一个ng-class="{{completed : todo.active == 0}}" 模型与另一个模型有多对一关系,我们称之为authAccess,这意味着用户可以拥有多本书,但一本书只能拥有一个老板。好的好。现在,我们有一个登录用户正在查询以查找他的所有书籍。他向User发出GET请求。我想确保过滤返回的Book对象,以便只返回他的书。

所以基本上在Sails中,我能够编写一个策略,将请求参数更改为/book,以便自动过滤生成的Book结果。这很方便,因为我能够使用相同的策略来过滤其他模型,例如{user: loggedInUser}Book或诸如此类的东西。我的问题是 - 在Django中实现相同功能的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

查看文档: http://www.django-rest-framework.org/api-guide/filtering/#filtering-against-the-current-user

最有可能最好在模型视图集中覆盖get_queryset方法。您可以通过为视图创建基类来使其成为通用方法,例如:

from rest_framework import generics, viewsets, mixins, generics


class OwnerModelViewSet(viewsets.ModelViewSet):

    def get_queryset(self):
        """
        This view should return a list of all the records
        for the currently authenticated user.
        """
        return self.model.objects.filter(user=self.request.user)

您的所有模型视图集类都可以从该类继承。这将要求外键字段始终被命名为“user”。如果不是这种情况,那么如何在User表中找到一个外键字段是一种有点hacky的方式。小心使用。

from django.db.models.fields.related import ForeignKey 
from accounts.models import User

def _get_related_user(self, obj):
    '''
     Search for FK to user model and return field name or False if no FK.
     This can lead to wrong results when the model has more than one user FK.
    '''
    for f in self.model._meta.fields:
        if isinstance(f, ForeignKey) and f.rel.to == User:
            return f.name
    return False