Home > Mobile >  django get latest release QuerySet
django get latest release QuerySet

Time:07-21

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):
    # pass


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

is it possible to get a queryset of latest releases of each project if it has release? sorry I literally have no idea how to write the queryset.


I am sorry that I posted the wrong model, project field is meant to be on Release model, just a copy and paste issue.

CodePudding user response:

There is a way to do this in a single query, you will need to combine annotate and filter together.

The method is to annotate each object with the highest version for each project related to the release. So we use a double-underscore through relation of project__releases__version. This gets the project related to each release, gets all of the related releases to that project and thus all of the versions.

We can apply Max to that field to get the highest one. Once we know what the latest version is, we can simply filter the queryset for that value using an F() object, which gets the field value.

from django.db.models import Max, F

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

CodePudding user response:

You have to set relation properly. You should not connect Project to Project, if you want to have relation with Release :) It is much better to use direct relationship or model's method. Then you can easier use it anywhere outside.

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

Then in fuction (or shell):

def get_latest_releases():

    releases = []
    for project in Project.objects.all():
        if project.latest_release():
            releases.append(project.latest_release())
    return releases
  • Related