Home > Software design >  Django - Trying to order get_object_or_404 by latest
Django - Trying to order get_object_or_404 by latest

Time:11-10

I have a collection of blog post with a category defined for each. The single category page displays all post under the specified category, but I would like these to be sorted by the date written.

Here is what I have:

def single_category(request, slug):
    category = get_object_or_404(Category, slug=slug)
    categories = Category.objects.all()
    context = {
        'category': category,
        'categories': categories
    }
    return render(request, 'Blog/single-category.html', context)

This doesn't work, but here is what I want:

def single_category(request, slug):
    category = get_object_or_404(Category.objects.order_by('-written_on'), slug=slug)
    categories = Category.objects.all()
    context = {
        'category': category,
        'categories': categories
    }
    return render(request, 'Blog/single-category.html', context)

Here are my Category and Post models

class Category(models.Model):
    name = models.CharField(max_length=120)
    slug = models.SlugField(max_length=120)

    class Meta:
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return '/%s/' % self.slug


class Post(models.Model):
    name = models.CharField(max_length=120)
    slug = models.SlugField(max_length=120)
    post_category = models.ForeignKey(Category, related_name='post', 
    on_delete=models.CASCADE)
    post_summary = models.TextField(max_length=120)
    post_content = models.TextField()
    written_on = models.DateField()
    preview_image = models.ImageField()
    homepage_carousel_status = models.IntegerField(choices=STATUS, 
    default=0)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return '/%s/%s/' % (self.post_category.slug, self.slug)

CodePudding user response:

You can fetch the related Posts and order these in descending written_on order:

def single_category(request, slug):
    category = get_object_or_404(Category, slug=slug)
    posts = Post.objects.filter(post_category=category).order_by('-written_on')
    categories = Category.objects.all()
    context = {
        'category': category,
        'categories': categories,
        'posts': posts
    }
    return render(request, 'Blog/single-category.html', context)

In the template you thus then enumerate over posts, instead of category.post:

{% for post in posts %}
    …
{% endfor %}
  • Related