Search code examples
djangosortingsql-order-bydjango-tables2

Django-tables2: how to order_by accessor


Say we have a column like:

num_member = tables.Column(accessor = 'members.count', verbose_name = 'number of members' )

When I tried to sort this in the template, it raises:

Field Error: Cannot resolve keyword u'count' into field

I read the document and it says we can use order_by by passing in some sort of accessor, but how exactly do we do this please?


Solution

  • For function like Model's property method, you can access it directly using accessor. For example:

    Class MyModel(models.Model):
        data= models.CharField(max_length=255)
    
        @property
        def print_function(self):
           return 'hello world'
    
    #Table class
    class MyTable(tables.Table):
            data= tables.Column(accessor='print_function')
    
        class Meta:
            model = MyModel
            fields = ('data')
    

    Using the above method, you can show different kinds of data in table using accessor:

    Class SomeModel(models.Model):
        some_data= models.CharField(max_length=255)
        data= models.ManyToManyField(MyModel)
    
        @property
        def count_function(self):
           some_data= self.data.objects.count() #returns count of the objects
           return some_data
    
    #Table class
    class SomeTable(tables.Table):
        data= tables.Column(accessor='count_function')
    
        class Meta:
            model = SomeModel
            fields = ('data')
    

    And accessor can be used for directly accessing related foreignkey model's field value like:

    Class SomeModel(models.Model):
        somedata= models.ForeignKey(MyModel)
    
    
    #Table class
    class MyTable(tables.Table):
            data= tables.Column(accessor='somedata.data')
    
        class Meta:
            model = SomeModel
            fields = ('data')
    

    EDIT

    Lets give an example of how order_by can be used:

    #Class Based view, I am subclassing ListView and SingleTableView here for example
    
    class MyView(ListView, SingleTableView):
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['table'].order_by = '-last_updated' #last_updated is a datetimefield in model
            return context
    

    In the above code, what I have done is that, I am changing the order of the table data in context which will later be rendered in template.