Автоматическая генерация столбцов таблицы на Django с помощью представления
Я использую django и создаю таблицу из данных учебника. Когда я создавал свой .html, я легко получил цикл для записи данных из моего экземпляра выбора, но я не могу заставить то же самое работать для имен столбцов. Я видел здесь, как получить поля модели, но я не могу заставить цикл записать их для меня.
table.html
{% extends 'base.html'%}
{% block content%}
<div class="container">
<div class="row">
<p><h3 class="text-primary"> Python Django DataTables </h3></p>
<hr style="border-top:1px solid #000; clear:both;" />
<table id = "myTable" class ="table table-bordered">
<thead class = "alert-warning">
<tr>
<!-- i would like not to have to write those one by one for future projects -->
<th> Choice </th>
<th> Votes </th>
</tr>
</thead>
<tbody>
<!-- this is the kind of loop I wanted for the columns-->
{% for item in qs %}
<tr>
<td contenteditable='true'>{{item.choice_text}}</td>
<td>{{item.votes}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content%}
views.py
class ChoiceTableView(TemplateView):
model = Question
template_name = 'polls/table.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["qs"] = Choice.objects.all()
return context
models.py
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
Если вам нужен шаблон, который может выполнять полностью автоматическую печать заголовка и значений, вы можете сделать это с помощью другого набора queryset:
context["qs"] = Choice.objects.all().values( 'the', 'fields', 'you', 'want')
а в шаблоне каждый "объект" - это словарь {'the':value_of_the, 'fields':..., ...}
. Итак, object.keys()
- это заголовки, а object.values
- соответствующие данные.
Итак, я думаю, что это может сработать (может потребоваться отладка)
<table id = "myTable" class ="table table-bordered">
{% for item in qs %}
{% if forloop.first %}
<thead class = "alert-warning">
<tr>
{% for name in item.keys %} <th>{{name}}</th> {% endfor %}
</tr>
</thead>
<tbody>
{% endif %}
<!-- still in the outer loop iterating over qs -->
<tr>
{% for value in item.values %}
<td {% if forloop.first %}contenteditable='true'{%endif%} >{{value}}</td>
<!-- the above forloop.first refers to the INNER loop -->
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Однако, вы получите choice_text
в качестве заголовка столбца, а не choice
, поэтому я считаю, что лучше передавать заголовки в контексте:
context["qs"] = Choice.objects.all().values( 'choice_text', 'votes')
context["headers"] = ('Choice','Votes')
, что также сделало бы шаблон более читабельным без необходимости использования forloop.first
. Вместо этого - два внешних цикла, один для заголовка и один для тела. Если вы используете .values_list
вместо .values
в queryset, вы получите список списков вместо списка диктов, который тогда не нуждается в .values
в шаблоне, только {% for value in item %}