【问题标题】:Django: Filter request results to only contain data related to the requesting userDjango:过滤请求结果以仅包含与请求用户相关的数据
【发布时间】:2015-10-15 14:50:51
【问题描述】:

我是 Django 初学者(尽管我确实有使用 Sails.js + Angular 进行 Web 开发的经验)所以请耐心等待。

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

所以,是的,我已经为大多数事情找到了相应的功能。我还没有找到一个替代 Sails.js 功能的东西,称为“策略”。它们是可以在对某些控制器操作的查询上执行的功能,并且可以定义为特定于模型、特定于模型控制器操作和特定于请求类型。例如,您可以有一个“authAccess”策略来检查请求的用户是否经过身份验证,并且在实际请求的控制器方法执行之前执行该策略。您还可以在将请求对象传递给控制器​​之前使用它们来修改它们。现在到我的实际问题:

假设我有一个User 模型,它与另一个模型具有多对一关系,我们称之为Book,这意味着用户可以拥有很多书,但一本书只能有一个所有者。太好了。现在,我们有一个登录用户正在查询以查找他的所有书籍。他向/book 发出GET 请求。我想确保过滤返回的Book 对象,以便只返回他的书。

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

【问题讨论】:

    标签: python django rest request sails.js


    【解决方案1】:

    查看文档: 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 表的外键字段。小心使用。

    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
    

    【讨论】:

      猜你喜欢
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      相关资源
      最近更新 更多