Search code examples
djangodjango-modelsdjango-templatesdjango-viewsdjango-tables2

django-tables2 cannot sort on certain fields


I have a Django model defined as follows:

class DummyModel(models.Model):
    name = models.CharField(max_length=100, name='Name')
    description = models.CharField(name='Description', max_length=150)
    time_points = models.PositiveIntegerField(name="Time Points")
    more_text = models.CharField(max_length=100, name="More Text")

    class Meta:
        db_table = "dummy"

I would like to later do some customization so I have a table class as well:

class DummyTable(tables.Table):
    class Meta:
        model = DummyModel
        attrs = {'class': 'paleblue'}

I have a corresponding view which is as follows:

@login_required(login_url="login/")
def review(request):
    table = DummyTable(DummyModel.objects.all())
    RequestConfig(request).configure(table)
    return render(request, 'review.html', {'reviews': table})

Finally, I render it ion my template using:

{% block content %}
    {% load static %}
    {% load render_table from django_tables2 %}
    <div class="function-container">
        {% render_table reviews %}
    </div>
{% endblock %}

Now this renders fine but when i try to sort the time Points column (by clicking on the column header), it comes with the error:

Invalid order_by arguments: [u'Time Points']
Request Method: GET
Request URL:    http://127.0.0.1:8000/review/?sort=Time+Points
Django Version: 1.10.5
Exception Type: FieldError
Exception Value:    
Invalid order_by arguments: [u'Time Points']

However, if I point the browser to http://127.0.0.1:8000/review/?sort=time_points, this works. So, somehow the correct field name is not passed. I tried changing the name and adding verbose_namne fields as:

time_points = models.PositiveIntegerField(name="time_points", verbose_name="Time Points")

However, this returns in no such column: dummy.time_points


Solution

  • I figured out a way to do this, which is to override the columns in my table class. So, now my model simply looks like:

    class DummyModel(models.Model):
        name = models.CharField(max_length=100)
        description = models.CharField(max_length=150)
        time_points = models.PositiveIntegerField()
        more_text = models.CharField(max_length=100)
    
        class Meta:
            db_table = "dummy"
    

    And in my custom table class, I have:

    class DummyTable(tables.Table):
        #Override here to change the column header text 
        time_points = tables.Column(verbose_name='Time Points')
        more_text = tables.Column(verbose_name='More Text')
    
        class Meta:
            model = DummyModel
            attrs = {'class': 'paleblue'}
    

    Now the sorting works as expected.