Django1.4: How to use order_by in template?

12,788

Solution 1

The order_by needs at least one argument, and Django does not allow you to pass arguments to a function or method inside a template.

Some alternatives are:

  • Use Jinja2 template engine instead of Django's one (Jinja2 will let you pass arguments to methods and is said to perform better)
  • order the dataset in the view
  • use the "Meta:ordering" attribute to define a default ordering criteria for your models
  • write a custom filter so you can queryset|order_by:'somefield' (see this snippet)
  • as suggested by Michal, you can write a custom Manager with predefined methods for the orderings you need

Solution 2

Check out the dictsort filter, it's pretty much what you're looking for I think.

Share:
12,788
chobo
Author by

chobo

Updated on June 13, 2022

Comments

  • chobo
    chobo almost 2 years

    Django1.4: How to use order_by in template?

    models.py

    from django.db import models
    from django.contrib.auth.models import User
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes import generic
    
    class Note(models.Model):
        contents = models.TextField()
        writer = models.ForeignKey(User, to_field='username')
        date = models.DateTimeField(auto_now_add=True)
    
        content_type = models.ForeignKey(ContentType)
        object_id = models.PositiveIntegerField()
        content_object = generic.GenericForeignKey('content_type', 'object_id')
    
    
    class Customer(models.Model):
        name = models.CharField(max_length=50,)
        notes = generic.GenericRelation(Note, null=True)
    

    Above is my models.py.

    I want to use 'order_by'(https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by)

    And...

    views.py

    from django.views.generic import DetailView
    from crm.models import *
    
    class customerDetailView(DetailView):
        context_object_name = 'customerDetail'
        template_name = "customerDetail.html"
        allow_empty = True
        model = Customer
        slug_field = 'name'
    

    My views.py use DetailView(https://docs.djangoproject.com/en/1.4/ref/class-based-views/#detailview).

    And

    customerDetail.html

    <table class="table table-bordered" style="width: 100%;">
        <tr>
            <td>Note</td>
        </tr>
        {% for i in customerDetail.notes.all.order_by %}<!-- It's not working -->
            <tr>
                <th>({{ i.date }}) {{ i.contents }}[{{ i.writer }}]</th>
            </tr>
        {% endfor %}
    </table>
    

    I want to use order_by in template...

    What should I do?

    • rxdazn
      rxdazn about 11 years
      have you tried queryset = Customer.objects.order_by() in customerDetailView?
    • chobo
      chobo about 11 years
      Yeah, I tried queryset = Customer.objects.order_by('note__date') and queryset = Customer.objects.order_by('note__date'). But failed...
  • Michal Čihař
    Michal Čihař about 11 years
    ...or use custom Manager for the class which will provide you predefined ways of ordering
  • chobo
    chobo about 11 years
    I don't know understand fourth tip "write a custom filter so you can queryset|order_by:'somefield'". Could you give me ... some example code?
  • chobo
    chobo about 11 years
    Anyway I solved it. class Meta: ordering = ['date'] (in models.py)
  • Paulo Scardine
    Paulo Scardine about 11 years
    cathy answer has such sample code, seems like she is using the same snippet (but she forgot to attribute the solution to the original author). Also, you need to place this file in some specific location in order to be able to load it inside the template.
  • Corentin S.
    Corentin S. over 8 years
    This is the easiest answer and it does work on querysets.
  • Muhammad Zubair
    Muhammad Zubair about 2 years
    @chobo regarding the fourth tip, you may use the link he has provided or refer to this link. pluralsight.com/guides/… . The fourth tip worked for me