【问题标题】:Django- How to get last uploaded file into template?Django-如何将最后上传的文件放入模板中?
【发布时间】:2021-03-17 12:16:27
【问题描述】:

我正在创建一个用户可以上传声音文件的网站。他们可以查看用户上传的声音文件列表并进行播放。

这很有效。我用音频元素制作了一个对象列表的 for 循环。

但是,另外,我还希望能够仅将最近添加的声音文件单独放置在模板的底部,以便可以单独处理(即我想将它放在音频元素中与列表中的内容分开,也可以在模板中自行访问以使用 WebAudio API 处理它)。

我知道我需要使用过滤器,并且我一直在阅读 Model.objects.latest('field') 应该完成这项工作(我假设在 views.py 中)但是我做的事情非常错误,因为无论我输入什么我的观点和我的模板会产生错误。我正在使用基于类的视图和 Django 版本 3.1.7

如果有人可以向我展示我需要在模型、视图和模板中添加的内容,以便我可以从对象列表中获取最后添加的声音文件到我的模板中。我将不胜感激。

我的模型如下所示:

class SoundFile(models.Model):
    sound_file = models.FileField()  
    created_on = models.DateTimeField(auto_now_add=True, null=True)
    last_modified = models.DateTimeField(auto_now=True, null=True)

    def get_absolute_url(self):
        return reverse('download-file')  

我的观点是这样的:

class SoundUploadView(generic.CreateView):

   model = SoundFile
   fields = ['sound_file']
   template_name = 'upload.html'

class SoundDownloadView(generic.ListView):

    model = SoundFile
    fields = ['sound_file']
    template_name = 'download.html'

我的模板如下所示:

上传.html

{% extends "base_generic.html" %}

{% block content %}

<div class="container">
<form action="#" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.media }}
    {{ form.as_p }}
    <button class="btn btn-primary btn-sm" type="submit">Upload</button>
</form>
</div>
{% endblock %}

下载.html

{% extends "base_generic.html" %}

{% block content %}

  <div class="container">
    {% for document in object_list %}
    <p> {{ document.sound_file.name }} </p>
    <p> Created on: {{ document.created_on}} </p>
    <p> Last modified: {{ document.last_modified}} </p>    

        <audio controls id="player"><source src="{{ document.sound_file.url }}"></audio>
    {% endfor %}
  </div>
  
  <div>  
    <a class="button" href="../upload"> Upload your version</a>
  </div>

{% endblock %}

谢谢!

追溯: 如果我尝试通过添加以下内容在视图中应用过滤器:

def get_queryset(self):
    return SoundFile.objects.last()

所以整个视图是:

class SoundDownloadView(generic.ListView):

    model = SoundFile
    fields = ['sound_file']
    template_name = 'download.html'

    def get_queryset(self):
        return SoundFile.objects.last()

我收到以下回溯的错误:

Django Version:     3.1.7
Exception Type:     TypeError
Exception Value:    

'SoundFile' object is not iterable

Exception Location:     /Users/cameronharris/.virtualenvs/my_django_environment/lib/python3.9/site-packages/django/template/defaulttags.py, line 167, in render
Python Executable:  /Users/cameronharris/.virtualenvs/my_django_environment/bin/python3
Python Version:     3.9.2
Python Path:    

['/Users/cameronharris/django_test/Headroom',
 '/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
 '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
 '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
 '/Users/cameronharris/.virtualenvs/my_django_environment/lib/python3.9/site-packages']

【问题讨论】:

    标签: django


    【解决方案1】:

    您只向模板传递了一个 SoundFile 对象,然后您尝试在 for 循环中迭代该 single 对象,这就是您收到 'SoundFile' object is not iterable 错误的原因。

    ListView 在您必须显示对象列表时使用。在这里,在您的情况下,您只有一个要表示的对象,因此强烈建议使用Detilview

    但是如果你还想用ListView,那就试试这个

    <!-- removed the loop, change context name to object_list -->
    <p> {{ object_list.sound_file.name }} </p>
    <p> Created on: {{ object_list.created_on}} </p>
    <p> Last modified: {{ object_list.last_modified}} </p>    
    <audio controls id="player"><source src="{{ document.sound_file.url }}"></audio>
    

    【讨论】:

    • 非常感谢,这行得通!我唯一需要从您的答案中更改的是
    猜你喜欢
    • 2014-01-29
    • 2014-01-15
    • 2011-09-26
    • 2018-02-14
    • 1970-01-01
    • 2013-11-23
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多