Django get latest release QuerySet

class Release(models.Model):
    version = models.PositiveIntegerField(default=1)


class Project(models.Model):
    project = models.ForeignKey('projects.Project', related_name='releases', on_delete=models.SET_NULL, blank=1, null=1)


def getObjects():
    releases = []
    for project in Project.objects.all():
        if project.releases.all():
            releases.append(project.releases.all().order_by('-version')[0])
    return releases

можно ли получить кверисет последних релизов каждого проекта, если у него есть релиз? Извините, я буквально не представляю, как написать кверисет.

Есть способ сделать это в одном запросе, вам нужно объединить annotate и filter вместе.

Метод заключается в аннотировании каждого объекта с наивысшей версией для каждого проекта, связанного с релизом. Поэтому мы используем двойную аннотацию через отношение project__releases__version. Это позволяет получить проект, связанный с каждым релизом, получить все связанные с этим проектом релизы и, таким образом, все версии.

Мы можем применить Max к этому полю, чтобы получить наибольшее значение. Узнав последнюю версию, мы можем просто отфильтровать набор запросов для этого значения с помощью объекта F(), который получает значение поля.

from django.db.models import Max, F

Release.objects.annotate(
      latest_for_project=Max(project__releases__version)
   ).filter(
      latest_for_project=F('release')
   )

Вы должны правильно установить связь. Не следует соединять Project с Project, если вы хотите иметь связь с Release :) Гораздо лучше использовать прямые отношения или метод модели. Тогда вы сможете легче использовать его в любом другом месте вне системы.

class Release(models.Model):
    version = models.PositiveIntegerField(default=1)
    project = models.ForeignKey('projects.Project', related_name='releases', on_delete=models.SET_NULL, blank=1, null=1)


class Project(models.Model):
    # project fields

    def latest_release(self):
        return self.releases.order_by('-version').first()

Затем в фукции (или оболочке):

def get_latest_releases():

    releases = []
    for project in Project.objects.all():
        if project.latest_release():
            releases.append(project.latest_release())
    return releases
Вернуться на верх