Фильтрация дубликатов в наборе запросов на основе поля UUIDField

Я столкнулся с некоторыми проблемами при извлечении определенного списка объектов из моей базы данных. Я изучаю python/django после довольно долгого перерыва и чувствую себя довольно ржавым. В качестве упражнения я создаю приложение, которое позволяет группе друзей "разыгрывать" абонементы, например, по очереди выбирать, какие игры вы хотите посетить, пока все билеты не будут распределены.

Я решил поступить следующим образом: у меня есть одна модель базы данных, которая содержит дамп всех игр за весь сезон (SportSeason), и база данных, которая содержит информацию о драфте (TicketDraft). Поскольку будет много строк (для отслеживания выбора билетов/игр) для каждой сессии драфта, я создал поле UUID для логической группировки строк, относящихся к одному драфту.

models.py

class SportSeason(models.Model):
    year = models.IntegerField(default=None)
    sport = models.CharField(max_length=10, default=None)
    home = models.CharField(max_length=10)
    visitor = models.CharField(max_length=10)
    date = models.DateTimeField(auto_now=False)

    class Meta:
        app_label = 'ticket_draft'

class TicketDraft(models.Model):
    tt_group = models.IntegerField()
    tt_status = models.CharField(max_length=10)  # available, selected
    tt_owner = models.CharField(max_length=30)
    gm_date = models.DateTimeField(auto_now=False, null=True)
    team_home = models.CharField(max_length=10)
    team_visitor = models.CharField(max_length=10)
    draft_year = models.IntegerField()
    ssn_create = models.DateTimeField(auto_now=True)
    ssn_owner = models.CharField(max_length=30)
    ssn_status = models.CharField(max_length=10)  # active, cancelled, complete
    ssn_ident = models.UUIDField(default=uuid.uuid4, editable=False)

На главной странице я отображаю активные черновики на основе статуса сессии (ssn_status="ACTIVE"), но мне нужно уточнить это, чтобы включить уникальные UUID (ssn_ident). Кроме того, я хотел бы отображать домашнюю команду (team_home), но меня устраивает первое найденное вхождение, поскольку уникальные данные в других полях не имеют отношения к этому представлению.

views.py

def home_page_view(request):
    if request.method == 'POST':
        team = request.POST.get('home_team')
        tt_groups = int(request.POST.get('ticket_groups'))
        season = SportSeason.objects.filter(home=team)
        session_id = uuid.uuid4()
        for group in range(tt_groups):
            for game in season:
                row = TicketDraft(team_home=game.home,
                                  team_visitor=game.visitor,
                                  gm_date=game.date,
                                  draft_year=game.year,
                                  tt_group=group + 1,
                                  tt_status="AVAILABLE",
                                  ssn_owner="rsw",
                                  ssn_status="ACTIVE",
                                  ssn_ident=session_id,
                                  )
                row.save()
        return render(request, "index/index.html")
    else:
        sessions = TicketDraft.objects.filter(ssn_status="ACTIVE").distinct(TicketDraft.ssn_ident)
        new_draft = CreateDraft()
        context = {'arena_mappings': ARENA_MAPPINGS,
                   'team_mappings': TEAM_MAPPINGS,
                   'sessions': sessions,
                   'new_draft': new_draft,
                   }
        return render(request, "index/index.html", context)

Как и ожидалось, в разделе else: (GET) приведенного выше представления я возвращаю все игры в сессиях. Использование .distinct() не работает здесь, когда применяется к определенному полю, поэтому я не уверен, есть ли здесь чистое решение; или у меня фундаментальная проблема с тем, как я решил организовать свои данные.

Спасибо!

Я рекомендую вам прочитать этот раздел официальной документации Django, который объясняет, как работает distinct.

Предполагая, что вы используете базу данных PostgreSQL, вам нужно добавить .order_by("ssn_ident") перед методом .distinct:

sessions = TicketDraft.objects.filter(ssn_status="ACTIVE").order_by("ssn_ident").distinct("ssn_ident")

Спасибо за ответы, я мог бы быть более ясным в своем первоначальном сообщении относительно использования mysql. Я просто решил эту проблему с помощью python вместо того, чтобы пытаться дополнительно фильтровать поток.

active = list(TicketDraft.objects.filter(ssn_status__exact="ACTIVE").values('ssn_ident',
                                                                                'team_home',
                                                                                'ssn_owner',
                                                                                'draft_year'))
sessions = [dict(t) for t in {tuple(d.items()) for d in active}]
Вернуться на верх