【问题标题】:Django: Offcanvas pdf preview iteration issueDjango:Offcanvas pdf预览迭代问题
【发布时间】:2021-03-28 17:03:41
【问题描述】:

大家好

我正在设置一个页面,其中有一个表格,其中包含一些关于 pdf 文件的元数据。

当然为了用户友好,我想给用户一个存储文件的预览,我想在画布外这样做。

我的 html 文件

 <h5>Add a document </h5>
  <div class="addition">
    <form method="POST" action="" enctype='multipart/form-data' autocomplete="off">
      {% csrf_token %}                


        <div>

            <input type="text" class="form-control form-control-sm" aria-describedby="emailHelp" placeholder="name" name="name" maxlength="50" autocomplete="off">
          </div>
          <div>
              <label for="myfile">Select a file:</label>
            <input type="file" id="myfile" name="pdf">
          </div>
        <div>
            <button type="submit" class="btn btn-sm btn-primary">Submit</button>
           </div>
         </form>
        </div>




       <h4>Overview documents</h4>
       <div class="table-responsive">
    <table class="table table-striped table-sm">
      <thead>
        <tr>
          <th>#</th>
          <th>Name</th>
          <th>Descritpion</th>
          <th></th>
          <th></th>

        </tr>
      </thead>
      <tbody>
        {% for item in all_pdfs %}   
            <tr>                    
            <td>{{ forloop.counter }}</td>
                <td>{{ item.name }}</td>
                <td><a href="{{item.pdf.url}}">{{ item.name }}</a></td>
                <td>
              <div>
                    <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight">Toggle right offcanvas</button>

                        <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasRight" aria-labelledby="offcanvasRightLabel">
                          <div class="offcanvas-header">
                            <h5 id="offcanvasRightLabel">Offcanvas right</h5>
                            <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
                          </div>
                          <div class="offcanvas-body">
                             <embed src="{{ item.pdf.url }}" type="application/pdf" height="700px" width="350">
                          </div>
                        </div>
              </div>
                </td>
          </tr>

            {% endfor %}
        </tbody>
    </table>
</div>

此 html 页面包含 2 个部分:实际表单和代表我数据库中所有记录的表格下方

models.py

class TestPDF(models.Model):
name = models.CharField(max_length=50, default=None, null=True, blank=True)
pdf = models.FileField(upload_to='test')

views.py

def test(request):
all_pdfs = TestPDF.objects.all()
    if request.method == "POST":
        settings_form = TestPDFForm(request.POST or None, request.FILES or None)

        if settings_form.is_valid():
            settings_form.save()

        return render(request, 'test.html', {"all_pdfs": all_pdfs})
    else:
        return render(request, 'test.html', {"all_pdfs": all_pdfs})
return render(request, 'test.html', {"all_pdfs": all_pdfs})

最后是我的

forms.py

class TestPDFForm(forms.ModelForm):
class Meta:
    model = TestPDF
    fields = ['name', 'pdf']

正常行为 我想单击一个随机按钮并在 offcanvas 中查看相应的 pdf 文档

问题: 当我单击任何东西上的按钮时,我在画布中得到错误的预览。我总是得到第一个 pdf,而表中的链接正确对应于正确的 PDF。 因此,由于某种原因,offcanvas 无法在最后一个表中正确迭代。这个问题困扰了我很长一段时间,我还没有找到任何解决方案。

非常感谢您的想法!

【问题讨论】:

  • id="offcanvasRight" 你正在一个循环中写这个。 id 应该是唯一的。 (很可能这是问题所在,我没有看到您的 javascript,但很可能它会尝试选择 ID 为 data-bs-target 指向的元素,并且鉴于有多个相同的 ID,只有第一个被选中)

标签: python html django pdf


【解决方案1】:

id 属性在 html 文档中应该是唯一的。参考https://www.w3.org/TR/2011/WD-html5-20110525/...

id 属性指定其元素的唯一标识符 (ID)。 该值在元素所在位置的所有 ID 中必须是唯一的 子树,并且必须至少包含一个字符。

当我们在一个循环中需要多个 id 时我们应该怎么做?使用forloop.counter(参考for template tag [Django docs])制作唯一的ID。

{% for item in all_pdfs %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td>{{ item.name }}</td>
        <td><a href="{{item.pdf.url}}">{{ item.name }}</a></td>
        <td>
            <div>
                <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight-{{ forloop.counter }}" aria-controls="offcanvasRight">Toggle right offcanvas</button>
                <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasRight-{{ forloop.counter }}" aria-labelledby="offcanvasRightLabel-{{ forloop.counter }}">
                    <div class="offcanvas-header">
                        <h5 id="offcanvasRightLabel-{{ forloop.counter }}">Offcanvas right</h5>
                        <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
                    </div>
                    <div class="offcanvas-body">
                        <embed src="{{ item.pdf.url }}" type="application/pdf" height="700px" width="350"> </div>
                    </div>
                </div>
        </td>
    </tr>
{% endfor %}

【讨论】:

  • 是的,我首先想到了您的第一条评论,因为我并不完全清楚您的意思(我认为这些 id 更多地用于绑定 html 元素)并且我确实用 @ 修复了它987654326@我觉得这个方案隔音好一点,因为它是我的pk?
  • @Gerhand offcanvasRight{{ item.id }} 确实也可以。我使用forloop.counter 是考虑到人们可能不希望人们找出相关对象的数据库ID。
  • 确实如此。我可能不得不为此想办法。但是就多个经过身份验证的用户何时在线而言,系统不会因为多个人可以拥有相同的 forloop 编号而出现问题吗?
  • @Gerhand 无需担心。 JavaScript 是客户端,这意味着它在客户端机器上运行。因此,当他们单击按钮时,脚本只会在他们的机器上运行,而不是在其他机器上运行。
  • 好的,谢谢,那么我可能会完全改用您的解决方案
猜你喜欢
  • 2022-08-20
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 2011-04-07
  • 2012-03-03
  • 2011-09-16
相关资源
最近更新 更多