我需要在Django orm中查询俱乐部列表的终点.对于用户是俱乐部所有者或用户是锦标赛裁判的俱乐部(end_date为空,或者end_date比现在更近).

我有模特:

class User(AbstractBaseUser):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, max_length=128)
    ...

class Club(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, max_length=128)
    owner = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)

class Tournament(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, max_length=128)
    club = models.ForeignKey(Club, on_delete=models.CASCADE)

class TournamentReferee(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, max_length=128)
    tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE, related_name='tournament_referee')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    end_date = models.DateTimeField("access expire date", blank=True, null=True)

我像这样创建了我的查询,但也许有更好的方法来使用单个查询来完成它?

    def get_queryset(self):
        if self.request.method == 'GET':
            now = datetime.datetime.now()
            referee_clubs_list = TournamentReferee.objects.filter(Q(user=self.request.user), (Q(end_date__isnull=True) | Q(end_date__gte=now))).values_list('tournament__club_id')
            return Club.objects.filter(Q(owner=self.request.user) | Q(id__in=(referee_clubs_list)))
        return super().get_queryset()

推荐答案

您可以使用以下命令查询

from django.db.models import Q
from django.utils.timezone import now


def get_queryset(self):
    if self.request.method == 'GET':
        return Club.objects.filter(
            Q(owner=self.request.user)
            | (
                Q(tournament__tournament_referee__user=request.user)
                & (
                    Q(tournament__tournament_referee__end_date=None)
                    | Q(tournament__tournament_referee__end_date__gte=now())
                )
            )
        ).distinct()
    return super().get_queryset()

这将使LEFT OUTER JOIN成为TournamentTournamentReferee型号的表格..distinct() [Django-doc]调用保证Club项最多出现一次.

Django相关问答推荐

Django REST framework:object has no attributed after annotation;Got attributeError when try to get a value for field field on serializer<>

Django-admin 显示decorator 按多列排序

如何使更新记录在 Django 模型中传递信号?

使用 Pytest 在 Django 中编写测试用例时如何加载特定目录中的所有固定装置

表单集中的每个表单验证

Django 有脚手架吗?

Django JSONField 过滤

未捕获的类型错误:$(...).datepicker is not a function(anonymous function)

如何将 Django forms.ChoiceField 呈现为 Twitter Bootstrap 下拉菜单

用户组和权限

django.core.exceptions.ImproperlyConfigured:请求设置 USE_I18N,但未配置设置

Django ALLOWED_HOSTS IP 范围

Django ORM 能否以可靠的与后端无关的方式存储无符号 64 位整数(又名 ulong64 或 uint64)?

模拟 Django 查询集以测试采用查询集的函数

Django - 每 x 秒运行一个函数

django 模板列表变量中的最后一个元素

Django - 一起为 2 个或更多字段创建唯一的数据库约束

如何过滤(或替换)在 UTF-8 中占用超过 3 个字节的 unicode 字符?

如何 suppress Django 中的弃用警告?

Django 多项 Select 字段/复选框 Select 多个