Django ORM получить последние данные каждой группы - PullRequest
0 голосов
/ 15 января 2020

Я хочу получить c все условия пользователя, последние данные соглашения. Три - таблица терминов, которая имеет название терминов. В таблице TermsAgreeHistory существует история соглашений пользователей

class TermsAgreeHistory(model.Model):
    user = models.CharField()
    terms = models.ForeignKey(Terms)
    date_signed = models.DateTimeField(auto_now_add=True)
    is_agreed = models.BooleanField(default=True)

class Terms(models.Model):
    name = models.CharField(unique=True)

термины - это внешний ключ

         TermsAgreeHistory
pk  user   terms   data_signed   is_agreed
----------------------------------------
1   Jack     1      20-01-01         Y
2   Jack     1      19-01-01         Y
3   Jack     2      20-01-01         N
4   Jack     2      19-01-01         N
5   Jack     3      20-01-01         Y
6   SAM      3      20-01-01         Y

Под таблицей есть каталог терминов

       Terms
 pk         name
 --------------------     
 1       member_term   
 2       search_term
 3       share_term

Я хочу найти Джека последнее соглашение и дата подписания условий в таблице условий. Используя Django ORM.

              result
----------------------------------------
1   Jack     member_term   20-01-01         Y
3   Jack     search_term   20-01-01         N
5   Jack     share_term    20-01-01         Y

Самое важное, что моя БД: mysql -> не может использовать отдельный метод для столбца. Как мне написать код?

1 Ответ

0 голосов
/ 16 января 2020

Это немного уродливо и медленно, но это лучший способ, который я нашел.

from django.db.models import Prefetch, Subquery, OuterRef

terms_history = TermsAgreeHistory.objects\
    .filter(terms_id=OuterRef("terms_id")\
    .order_by("-id")\
    .values("id")[:1]
newest = TermsAgreeHistory.objects.filter(id__in=Subquery(terms_history))
terms = Terms.objects\
    .prefetch_related(
        Prefetch("termsagreehistory_set", queryset=newest, to_attr="newest_history")
    )\
    .all()

Если вам нужно, чтобы он был очень быстрым, вы можете посмотреть, как поместить триггер в свою БД для самые последние TermsAgreeHistory для каждого Terms: https://dba.stackexchange.com/a/243988/186435

...