首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django选择与条件间接相关的

Django选择与条件间接相关的
EN

Stack Overflow用户
提问于 2020-03-12 14:18:37
回答 1查看 90关注 0票数 0

在我的项目中,我有Users,他们可以扮演一定的角色。但是,角色受日期范围的限制,即用户可以在01.01.2020至02.02.2020之间具有管理角色,在02.02.2020至03.03.2020之间具有非特权用户角色。

我需要能够返回具有当前角色的用户列表,并且我希望能够只对数据库进行一次查询。但是,我不知道该怎么做。

以下是我的模特:

代码语言:javascript
复制
class User(models.Model):
    ...

class Role(models.Model):
    name = models.CharField(...)

class UserRoleQuerySet(models.QuerySet):
    def current():
        return self.filter(period__contains=date.today())

class UserRoles(models.Model):
    user = models.ForeignKey(User, related_name='roles')
    role = models.ForeignKey(Role)
    period = DateTimeRangeField()

    objects = UserRoleQuerySet.as_manager()

我需要一个带有调用它的prefetch_relatedselect_relatedannotate方法的查询集,这样当我执行下面这样的代码时,就不会得到额外的数据库访问:

代码语言:javascript
复制
users = User.objects.(some_magic_here).all()
for user in users:
    print(user.role)

UPD:更具体地说,如果我不执行任何注释、预取或select_related,我将得到所有(当前)用户角色的打印输出。但是,每次迭代都将访问db以选择当前角色。我想要的是同样的打印输出,但不需要额外的往返到db。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-12 17:15:34

要获得一组对象,您将需要prefetch_related,尽管您不能在预取之后更改(筛选)查询,因为Django将无法完成连接。因此,在Django进行预取时,需要提供过滤器:

代码语言:javascript
复制
users = Users.objects.prefetch_related(
    Prefetch(
        'roles',
        queryset=(
            UserRoles.objects
                .filter(period__contains=date.today())
                .select_related('role')
        )
    )
)

当您在users中迭代时,同样地,如果您更改了查询,那么每次迭代都会对数据库造成额外的打击,所以没有执行以下操作:

代码语言:javascript
复制
for user in users:
    print(user.roles.first().role)

您需要执行如下操作,以避免对数据库的进一步查询,因为知道user.roles.all()总是只给出一个结果:

代码语言:javascript
复制
for user in users:
    for user_role in user.roles.all():
        print(user_role.role)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60656006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档