Hi,
While using django-simple-history I would like to change the model fields name to display the verbose_name instead.
I know this topic has been discussed before (How to display verbose_name in HTML template). But I’m stuck and maybe someone can help me fix the issue that occurs.
I get this: AttributeError: 'str' object has no attribute '_meta'
, and I’m not sure how to solve that issue.
My setup:
models.py:
from simple_history.models import HistoricalRecords
class Poll(models.Model):
question = models.CharField(max_length=200, verbose_name="The question")
pub_date = models.DateTimeField(verbose_name="Date Published ")
history = HistoricalRecords()
def __str__(self):
return self.question
My views.py:
def history(request, poll_id):
poll = Poll.objects.get(pk=poll_id)
p = poll.history.all()
changes = []
if p is not None and poll_id:
last = p.first()
for all_changes in range(p.count()):
new_record, old_record = last, last.prev_record
if old_record is not None:
delta = new_record.diff_against(old_record)
changes.append(delta)
last = old_record
return render(request, 'django_history/historik.html', {
'poll': poll,
'changes': changes,
})
My template:
<body>
<h2>Test history: {{poll.question}}</h2>
<h3>Changes made:</h3>
<table>
<thead>
<tr>
<th>id</th>
<th>date/time</th>
<th>change made</th>
<th>user</th>
</tr>
</thead>
<tbody>
{% for change in changes %}
<tr>
<td>{{change.new_record.history_id}}</td>
<td>{{change.new_record.history_date}}</td>
<td>
{% if change.changed_fields|length > 0 %}
{% for change_by_id in change.changes %}
<b>{{change_by_id.field|verbose_name:change_by_id.field}}</b> From:
{% if change_by_id.old %}
<b>{{change_by_id.old}}</b>
{% else %}
<b>blank field</b>
{% endif %}
to ---> <b>{{change_by_id.new}}</b>
<br>
{% endfor %}
{% else %}
There was no changes in this edition
{% endif %}
</td>
<td>{{change.new_record.history_user}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
My custom_tags.py:
from django import template
register = template.Library()
@register.filter
def verbose_name(poll, field_name):
if poll._meta.get_field(field_name).verbose_name.islower:
return poll._meta.get_field(field_name).verbose_name.capitalize()
else:
return poll._meta.get_field(field_name).verbose_name
If I change this line in the template: {{change_by_id.field|verbose_name:change_by_id.field}}
To: {{change_by_id.field|verbose_name}}
I get this error:
django.template.exceptions.TemplateSyntaxError: verbose_name requires 2 arguments, 1 provided
So if I change that again -
To: <b>{{change_by_id.field|title}}</b> From:
I see the model field names as is (Question / Pub_Date), but as mentioned above I’d like to see the verbose_name instead. So from the image below where “Question” is I’d like it to display “The question” as the verbose_name is in the model.
Little confused on how to solve it, maybe it’s a fairly easy fix (something I’m missing). Thanks for any help