Django Rest Framework 在 get_queryset 方法中过滤对象

如何解决Django Rest Framework 在 get_queryset 方法中过滤对象

基本上,我有一个目录视图集。在列表视图中,我想进行一些过滤并相应地返回。 相关的目录模型字段是:

class Catalog(models.Model):
    name = models.CharField(max_length=191,null=True,blank=False)
    ...
    team = models.ForeignKey(Team,on_delete=models.CASCADE,editable=False,related_name='catalogs')
    whitelist_users = models.JSONField(null=True,blank=True,default=list) # If white list is null,it is open to whole team

 

Views.py

class CatalogViewSet(viewsets.ModelViewSet):
    permission_classes = (IsOwnerAdminorRestricted,)

    def get_queryset(self):
        result = []
        user = self.request.user
        catalogs = Catalog.objects.filter(team__in=self.request.user.team_set.all())
        for catalog in catalogs:
            if catalog.whitelist_users == [] or catalog.whitelist_users == None:
                # catalog is open to whole team
                result.append(catalog)
            else:
                # catalog is private
                if user in catalog.whitelist_users:
                    result.append(catalog)
        return result

这就是我的逻辑;

1 - 如果目录的团队是当前用户的团队之一,则获取目录对象。

2 - 检查 catalog.whitelist_users 是否包含当前用户。 (还有一个例外,如果它没有意味着它对整个团队开放,所以我可以在列表视图中显示它。)

在这有效,但由于我正在返回一个数组,它没有正确找到详细信息对象。我的意思是 /catalog/ID 不能正常工作。

我是 DRF 的新手,所以我猜这里有问题。您将如何更好地实施这种过滤?

解决方法

想到的一个简单解决方案就是创建一个 PK 列表并再次过滤,这样您就可以返回一个查询集。不是最有效的解决方案,但应该有效:

def get_queryset(self):
    pks = []
    user = self.request.user
    catalogs = Catalog.objects.filter(team__in=user.team_set.all())
    for catalog in catalogs:
        if catalog.whitelist_users == [] or catalog.whitelist_users == None:
            # catalog is open to whole team
            pks.append(catalog.pk)
        else:
            # catalog is private
            if user in catalog.whitelist_users:
                pks.append(catalog.pk)
    return Catalog.objects.filter(id__in=pks)
,

顾名思义,你需要返回一个查询集。此外,如果没有必要,请避免迭代查询集。最好在一次数据库命中中完成。对于复杂的查询,您可以使用 Q object

from django.db.models import Q

# ...

    def get_queryset(self):
        user = self.request.user
        catalogs = Catalog.objects.filter(
                   Q(whitelist_users__in=[None,[]]) | Q(whitelist_users__contains=user),team__in=user.team_set.all())
                                                        
        return catalogs

现在我不能 100% 确定 whitelist_users__contains=user 会起作用,因为它取决于您构建 JSON 的方式,但想法就在那里,您只需要调整它包含的内容。

这将比在 python 中循环更有效,并且会尊重 get_queryset 的含义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?