django优化查询

yzckvree  于 2023-11-20  发布在  Go
关注(0)|答案(1)|浏览(99)

我需要在django中查询clubs list endpoint. with clubs,其中user是clubs所有者,或者user是Tournament resident(with empty end_date,or the end_date is more recent than now)。
我有模型:

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()

qncylg1j

qncylg1j1#

您可以使用

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 s成为TournamentTournamentReferee模型的表。.distinct()[Django-doc]调用保证Club项最多出现一次。

相关问题