Фильтрация дубликатов в наборе запросов на основе поля 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}]