Reputation: 344
I have a table which shows me the employees registered. I want to generate a simple HTML page according to their DB which includes their name, id, designation, etc.
To do so, I pass an id to the view so it can get the respective user's details and show me. Everything works fine until the error occurs object is not iterable. Here is my code below.
report.html
{% if emp_item %}
{% for some in emp_item %}
<title> {{ some.employee_name }} Report</title>
<h3>{{ some.employee_name }}</h3>
<table style="width:30%" border="4">
<td>{{some.id}}</td>
<td>{{some.Annual_leave}} </td>
<td>{{some.Sick_leave}} </td>
<td>{{some.allowed}} </td>
</table>
{% endfor %}
<h2>No User</h2>
{% else %}
{% endif %}
views.py
@staff_member_required # for admin login required
def report(request, id):
emp_item = Employee.objects.get(id=id)
context = {'emp_item': emp_item}
return render(request, 'projectfiles/report.html', context)
urls.py
url(r'^(?i)Rejectleaves/$', views.rejected_leave_show,
name='Reject_show'), # user leaves
url(r'^(?i)report/(?P<id>\d+)$', views.report,
name='Report'), # user Report
models.py
class Employee(models.Model):
allowed = models.BooleanField(default=True)
employee_name = models.OneToOneField(User, on_delete = models.CASCADE)
employee_designation = models.CharField(max_length = 5)
employee_department = models.CharField(max_length = 5)
Annual_leave = models.PositiveSmallIntegerField(default=5)
Sick_leave = models.PositiveSmallIntegerField(default=5)
I want to see each individual user's data according to the process they have made.
Upvotes: 13
Views: 48059
Reputation: 1
I got the same error below:
TypeError: 'Category' object is not iterable
Because I assigned the object made by get() to category__in
as shown below:
# Here # Here
Product.objects.filter(category__in=Category.objects.get(pk=1))
So, I assigned the queryset made by filter() to category__in
as shown below, then the error was solved:
# Here
Product.objects.filter(category__in=Category.objects.filter(pk=1))
Or, I removed __in from category__in
as shown below, then the error was solved:
# ↓ "__in" is removed
Product.objects.filter(category=Category.objects.get(pk=1))
Upvotes: 0
Reputation: 1810
You are iterating over emp_item
as an object list. But it is an object as Employee.objects.get(id=id)
returns a single object rather than a queryset.
So what you need to do is remove the for-loop
from the template as:
{% if emp_item %}
<title> {{ emp_item.employee_name }} Report</title>
<h3>{{ emp_item.employee_name }}</h3>
...and so on
{% else %}
<h2>No User</h2>
{% endif %}
But if you use get
while querying, there is a higher chance that you can get an exception of DoesNotExist
. So it is better if you can use Employee.objects.filter(id=id)
to avoid any exceptions.
The {% if emp_item %}
in your template is of no use if you are querying using get
.
For better use, you can use get
while querying and send a message to the template if exception occurs. For example:
def report(request, id):
try:
emp_item = Employee.objects.get(id=id)
return render(request, 'projectfiles/report.html', {'emp_item':emp_item})
except Employee.DoesNotExist:
return render(request, 'projectfiles/report.html', {'error': 'No data found.'})
Then in template:
{% if error %}
{{ error }}
{% else %}
<title> {{ emp_item.employee_name }} Report</title>
.... and so on to display other data
{% endif %}
Upvotes: 4
Reputation: 849
Change Employee.objects.get(id=id)
to Employee.objects.filter(id=id)
"filter()
will always give you a QuerySet" - it's iterable
get()
- return single object and it's not iterable
Upvotes: 39