I have a web page that show the details that is from my database, but when the user click on the view button, it did redirect me to the details page and get the id, but at the same time it give me an error 'Photo' object is not iterable, what is wrong with my code? How do I fix the error?
traceback error:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/details/6/
Django Version: 2.2.20
Python Version: 3.8.0
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account.apps.AccountConfig',
'crispy_forms']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django_session_timeout.middleware.SessionTimeoutMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Template error:
In template E:\Role_based_login_system-master\templates\logisticbase.html, error at line 67
'Photo' object is not iterable
57 : </div>
58 : {% endfor %}
59 : {% endif %}
60 : <div id="home_body">
61 : {% block content %}
62 :
63 : {% endblock %}
64 : </div>
65 : <!-- Optional JavaScript -->
66 : <!-- jQuery first, then Popper.js, then Bootstrap JS -->
67 : <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X 965DzO0rT 7abK41JStQIAqVgRVzpbzo5smXKp4Y fRvH 8abtTE1Pi6jizo" crossorigin="anonymous"></script>
68 : <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
69 : <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM B07jRM" crossorigin="anonymous"></script>
70 : </body>
71 : </html>
Traceback:
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "E:\Role_based_login_system-master\account\views.py" in details
312. return render(request, 'details.html', context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\shortcuts.py" in render
36. content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\loader.py" in render_to_string
62. return template.render(context, request)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\backends\django.py" in render
61. return self.template.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render
171. return self._render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in _render
163. return self.nodelist.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\loader_tags.py" in render
150. return compiled_parent._render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in _render
163. return self.nodelist.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\loader_tags.py" in render
62. result = block.nodelist.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\TAY\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\template\defaulttags.py" in render
165. values = list(values)
Exception Type: TypeError at /details/6/
Exception Value: 'Photo' object is not iterable
views.py
@login_required()
def details(request, pk):
allusername = Photo.objects.get(id=pk)
context = {'allusername': allusername}
print(pk)
return render(request, 'details.html', context)
details.html
{% extends "logisticbase.html" %}
{% block content %}
<style>
table {
border-collapse:separate;
border:solid black 1px;
border-radius:6px;
-moz-border-radius:6px;
}
td, th {
border-left:solid black 1px;
border-top:solid black 1px;
}
th {
border-top: none;
}
td:first-child, th:first-child {
border-left: none;
}
</style>
<script>
// Function to download table data into csv file
function download_table_as_csv(table_id, separator = ',') {
var rows = document.querySelectorAll('table#' table_id ' tr');
var csv = [];
for (var i = 0; i < rows.length; i ) {
var row = [], cols = rows[i].querySelectorAll('td, th');
for (var j = 0; j < cols.length; j ) {
var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
data = data.replace(/"/g, '""');
row.push('"' data '"');
}
csv.push(row.join(separator));
}
var csv_string = csv.join('\n');
var filename = 'export_' table_id '_' new Date().toLocaleDateString() '.csv';
var link = document.createElement('a');
link.style.display = 'none';
link.setAttribute('target', '_blank');
link.setAttribute('href', 'data:text/csv;charset=utf-8,' encodeURIComponent(csv_string));
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
</script>
<div style="padding-left:16px">
<br>
<div class="form-block">
<h5>Search for Part Number/ Reception Number/ Customer Name</h5>
<form class="form-inline my-2 my-lg-0" action="{% url 'gallery' %}" method='GET' value='{{ request.GET.q }}'>
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" name="q" value='{{ request.GET.q }}'/>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
<br>
<table id="viewTable" class="m-2">
<i class="fa fa-download" aria-hidden="true"></i>
<a href="#" onclick="download_table_as_csv('viewTable');">Download as CSV</a>
<br>
<tr class="header">
<th>Status</th>
<th>Log date</th>
</tr>
{% for photo in allusername %}
<tr>
<td>{{photo.Datetime}}</td>
<td>{{photo.status}}</td>
<td>{{photo.Datetime}}</td>
</tr>
{% endfor %}
</table>
<br>
</div>
</div>
{% endblock %}
gallery.html
{% extends "logisticbase.html" %}
{% block content %}
<style>
table {
border-collapse:separate;
border:solid black 1px;
border-radius:6px;
-moz-border-radius:6px;
}
td, th {
border-left:solid black 1px;
border-top:solid black 1px;
}
th {
border-top: none;
}
td:first-child, th:first-child {
border-left: none;
}
</style>
<script>
// Function to download table data into csv file
function download_table_as_csv(table_id, separator = ',') {
var rows = document.querySelectorAll('table#' table_id ' tr');
var csv = [];
for (var i = 0; i < rows.length; i ) {
var row = [], cols = rows[i].querySelectorAll('td, th');
for (var j = 0; j < cols.length; j ) {
var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
data = data.replace(/"/g, '""');
row.push('"' data '"');
}
csv.push(row.join(separator));
}
var csv_string = csv.join('\n');
var filename = 'export_' table_id '_' new Date().toLocaleDateString() '.csv';
var link = document.createElement('a');
link.style.display = 'none';
link.setAttribute('target', '_blank');
link.setAttribute('href', 'data:text/csv;charset=utf-8,' encodeURIComponent(csv_string));
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
</script>
<div style="padding-left:16px">
<br>
<div class="form-block">
<h5>Search for Part Number/ Reception Number/ Customer Name</h5>
<form class="form-inline my-2 my-lg-0" action="{% url 'gallery' %}" method='GET' value='{{ request.GET.q }}'>
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" name="q" value='{{ request.GET.q }}'/>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
<br>
<table id="viewTable" class="m-2">
<i class="fa fa-download" aria-hidden="true"></i>
<a href="#" onclick="download_table_as_csv('viewTable');">Download as CSV</a>
<br>
<tr class="header">
<th>Latest Log</th>
<th>Part Number</th>
<th>Serial Number</th>
<th>Reception/MCO Number</th>
<th>Customer Name</th>
<th>Status</th>
<th>View</th>
</tr>
{% for photo in allusername %}
<tr>
<td>{{photo.Datetime}}</td>
<td>{{photo.partno}}</td>
<td>{{photo.serialno}}</td>
<td>{{photo.reception}}/ {{photo.mcoNum}}</td>
<td>{{photo.Customername}}</td>
<td>{{photo.status}}</td>
<td>
<form action="{% url 'details' photo.id %}" method="post">
{% csrf_token %}
<button type="submit" class="btn btn-sm btn-info">View</button>
</form>
</td>
</tr>
{% endfor %}
</table>
<br>
</div>
</div>
{% endblock %}
This is how my gallery page looks like, so when the user click on the view button, it should get the ID and redirect them to the details page and view more in depth detail that is from the database.
CodePudding user response:
inside your details.html
change this
{% for photo in allusername %}
<tr>
<td>{{photo.Datetime}}</td>
<td>{{photo.status}}</td>
<td>{{photo.Datetime}}</td>
</tr>
{% endfor %}
to
<tr>
<td>{{allusername.Datetime}}</td>
<td>{{allusername.status}}</td>
<td>{{allusername.Datetime}}</td>
</tr>
the problem is that you are using a for loop over a non iterable object.
CodePudding user response:
When you use the get method in a queryset it will return only one object if found or a query does not exist error in that case if the object is not found. So you were trying to iterate over a single element that's why you are getting this error.
Just remove the for loop and maintian the rest of code like below.
<!-- not to include {% for photo in allusername %} -->
<tr>
<td>{{photo.Datetime}}</td>
<td>{{photo.status}}</td>
<td>{{photo.Datetime}}</td>
</tr>
<!-- {% endfor %} -->