django tables how to detect if table is empty
Asked Answered
C

5

6

I am new to django and web development and based on examples and help on SO, I have pieced together something which takes a model and renders it in a django-table. My template code is basically as follows:

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

The view is as follows:

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

This works fine. However, what I would like to do is show a message to the user saying that there are no records when the database table is empty. In the current setting, it shows an empty table with the columns which is probably not the best from a usability point of view.

Chino answered 13/3, 2017 at 11:40 Comment(0)
A
4

Probably the easiest way is in your template. Assuming your variable that's empty is called reviews:

{% block content %}
{% load static %}
{% if reviews %} 
   {% load render_table from django_tables2 %}
      <div class="function-page">
         <div class="table-form">
            <div class="function-container">
                {% render_table reviews %}
           </div>
         </div>
       </div>
{% else %} 
<span> Whatever holding response/error message you want. </span> 
{% endif %}
{% endblock %}

Per this this answer, for example, using {% if variable %} against a valid but empty variable, it generally evaluates to False, letting you use the {% if reviews %}.

However, if you need a really bulletproof check, you can do {{ value|default:"nothing" }} - from here.

You could also do it in your views, and pass an error message back to the template using the standard Messages framework included in Django:

from django.contrib import messages
messages.add_message(request, messages.INFO, "No reviews found, I'm afraid!.")

You need to include something like this in your templates to use messages:

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

Or you could do both! :)

Abet answered 13/3, 2017 at 11:45 Comment(5)
As per my comment to the other answer, I think the reviews table is always a valid variable. Is there a way to check for empty?Chino
Using {% if variable %} against a valid but empty variable, it generally evaluates to False, ime (see this answer, for example. However, if you need a really bulletproof check, you can do {{ value|default:"nothing" }} - from here.Abet
Ok, I explicitly set it to None in my view when the record count is 0 and it works.Chino
Great! I'd hazard that the DummyTable object that's not included in your code above is generating something that the template is reading as present, so not evaluating to False in that {% if%} statement. Glad you've got something that works. :)Abet
Yeah, it is probably because it is a django-tables instance which could be causing the issue ;) Thanks for your help.Chino
K
6

There are two options. Either you set empty_text inside class Meta

class Reviews(tables.Table):

    class Meta:
        empty_text = _("There are no reviews yet")

Or you can check it inside the template and avoid rendering table this way

{% if reviews_table.data.list %}
    {% render_table reviews_table %}
{% else %}
    <h1>There are no reviews yet</h1>
{% endif %}
Kilar answered 5/6, 2017 at 20:21 Comment(0)
A
4

Probably the easiest way is in your template. Assuming your variable that's empty is called reviews:

{% block content %}
{% load static %}
{% if reviews %} 
   {% load render_table from django_tables2 %}
      <div class="function-page">
         <div class="table-form">
            <div class="function-container">
                {% render_table reviews %}
           </div>
         </div>
       </div>
{% else %} 
<span> Whatever holding response/error message you want. </span> 
{% endif %}
{% endblock %}

Per this this answer, for example, using {% if variable %} against a valid but empty variable, it generally evaluates to False, letting you use the {% if reviews %}.

However, if you need a really bulletproof check, you can do {{ value|default:"nothing" }} - from here.

You could also do it in your views, and pass an error message back to the template using the standard Messages framework included in Django:

from django.contrib import messages
messages.add_message(request, messages.INFO, "No reviews found, I'm afraid!.")

You need to include something like this in your templates to use messages:

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

Or you could do both! :)

Abet answered 13/3, 2017 at 11:45 Comment(5)
As per my comment to the other answer, I think the reviews table is always a valid variable. Is there a way to check for empty?Chino
Using {% if variable %} against a valid but empty variable, it generally evaluates to False, ime (see this answer, for example. However, if you need a really bulletproof check, you can do {{ value|default:"nothing" }} - from here.Abet
Ok, I explicitly set it to None in my view when the record count is 0 and it works.Chino
Great! I'd hazard that the DummyTable object that's not included in your code above is generating something that the template is reading as present, so not evaluating to False in that {% if%} statement. Glad you've got something that works. :)Abet
Yeah, it is probably because it is a django-tables instance which could be causing the issue ;) Thanks for your help.Chino
M
3

test against table.paginated_rows it will be empty and evaluated to False when the table have no data.

they use this in django_tables2/templates/django_tables2/bootstrap.html:~26 template:

{% for row in table.paginated_rows %}
    ...
{% empty %}
    ... {{ table.empty_text }}
{% endfor %}
Medicate answered 4/12, 2018 at 9:48 Comment(0)
J
1

Do this:

{% if reviews %}
<div class="function-page">
    <div class="table-form">
       <div class="function-container">
           {% render_table reviews %}
       </div>
    </div>
</div>

{% else %}
<div>
    <p> Message to use </p>
</div>

{% endif %}
Janise answered 13/3, 2017 at 11:43 Comment(2)
I think the reviews table is always a valid variable. Is there a way to check for empty?Chino
If it is empty then the if statement will no be executed.Janise
E
0

Milano answer worked to me, but removing ".list" from the if conditional:

{% if reviews_table.data.list %}
    {% render_table reviews_table %}
{% else %}
    <h1>There are no reviews yet</h1>
{% endif %}
Eccrinology answered 31/3, 2021 at 17:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.