'Photo' 对象不可迭代

'Photo' object is not iterable

我有一个网页显示来自我的数据库的详细信息,但是当用户单击查看按钮时,它确实将我重定向到详细信息页面并获取了 id,但同时它给出了我的错误 'Photo' object is not iterable,我的代码有什么问题?我该如何修复错误?

错误:

回溯错误:

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 %}

这就是我的画廊页面的样子,所以当用户点击查看按钮时,它应该获取 ID 并将他们重定向到详细信息页面并查看来自数据库的更深入的详细信息。

在你的details.html
里面 改变这个

         {% for photo in allusername %}


       <tr>
        <td>{{photo.Datetime}}</td>
      <td>{{photo.status}}</td>
      <td>{{photo.Datetime}}</td>


  </tr>
{% endfor %}

           <tr>
        <td>{{allusername.Datetime}}</td>
      <td>{{allusername.status}}</td>
      <td>{{allusername.Datetime}}</td>


  </tr>

问题是您正在对不可迭代对象使用 for 循环。

当您在查询集中使用 get 方法时,它将 return 只有一个对象(如果找到)或查询不存在错误(如果找不到对象)。所以您试图迭代单个元素,这就是您收到此错误的原因。

只需删除 for 循环并维护其余代码,如下所示。

  <!-- not to include    {% for photo in allusername %} -->    
  <tr>
      <td>{{allusername.Datetime}}</td>
      <td>{{allusername.status}}</td>
      <td>{{allusername.Datetime}}</td>    
  </tr>

  <!-- {% endfor %}  -->