Think about the models:

class Author(models.Model):
	name = models.CharField(max_length=200, unique=True)

class Book(models.Model):
	pub_date = models.DateTimeField()
	author = models.ForeignKey(Author)

Now suppose I wish to order all of the books by, say, their pub_date. I'd use order_by('pub_date'). But let's say I would like a listing of authors purchased based on who most lately released books?

It is quite simple whenever you consider it. It's basically:

  • The writer on the top is the one that most lately released a magazine
  • The next is the one that released books less new because the first,
  • The like etc.

I possibly could most likely hack something together, consider this might grow large, I have to realize that I am doing the work right.

Help appreciated!

Edit: Lastly, would a choice of just adding a brand new area to them to exhibit the date from the last book and merely upgrading the whole time be superior?

Lastly, would a choice of just adding a brand new area to them to exhibit the date from the last book and merely upgrading the whole time be superior?

Really it might! This can be a normal denormalization practice and can be achieved such as this:

class Author(models.Model):
    name = models.CharField(max_length=200, unique=True)
    latest_pub_date = models.DateTimeField(null=True, blank=True)

    def update_pub_date(self):
        try:
            self.latest_pub_date = self.book_set.order_by('-pub_date')[0]
            self.save()
        except IndexError:
            pass # no books yet!

class Book(models.Model):
    pub_date = models.DateTimeField()
    author = models.ForeignKey(Author)

    def save(self, **kwargs):
        super(Book, self).save(**kwargs)
        self.author.update_pub_date()

    def delete(self):
        super(Book, self).delete()
        self.author.update_pub_date()

This is actually the third common option you've besides two already recommended:

  • doing the work in SQL having a join and grouping
  • getting all of the books to Python side and take away replicates

These two options decide to compute pub_dates from the stabilized data at that time while you're reading them. Denormalization performs this computation for every author at that time whenever you write new data. The concept is the fact that most web applications do reads most frequently than creates which means this approach is more suitable.

Among the perceived disadvantages of the is the fact that essentially you will find the same data in various places also it requires you to definitely ensure that it stays synchronized. It horrifies database individuals to dying usually :-). But normally, this is no problem before you make use of your ORM model to utilize dat (that you simply most likely do anyway). In Django it is the application that controls the database, not the other way round.

Another (more realistic) bad thing is by using the naive code that I have proven massive books update might be way reduced given that they ping authors for upgrading their data on each update regardless of what. Normally, this is solved by getting a flag to temporarily disable calling update_pub_date and calling it by hand later on. Essentially, denormalized data requires more maintenance than stabilized.

 def remove_duplicates(seq): 
    seen = {}
    result = []
    for item in seq:
        if item in seen: continue
        seen[item] = 1
        result.append(item)
    return result


# Get the authors of the most recent books
query_result = Books.objects.order_by('pub_date').values('author')
# Strip the keys from the result set and remove duplicate authors
recent_authors = remove_duplicates(query_result.values())

Or, you can adjust something similar to this:

Author.objects.filter(book__pub_date__isnull=False).order_by('-book__pub_date')

from django.db.models import Max Author.objects.annotate(max_pub_date=Max('books__pub_date')).order_by('-max_pub_date')

this involves that you employ django 1.1

and that i assumed you'll give a 'related_name' for your author area in Book model, so it will likely be known as by Author.books rather than Author.book_set. its a lot more readable.

Building on ayaz's solution, how about: Author.objects.filter(book__pub_date__isnull=False).distinct().order_by('-book__pub_date')