【问题标题】:How to link a Django model's property in HTML audio source tags?如何在 HTML 音频源标签中链接 Django 模型的属性?
【发布时间】:2019-10-28 20:46:06
【问题描述】:

感谢 Django 文档和类似问题的 Stack Overflow,我已经设法解决了这个问题,但我似乎无法在我的 html 的 <source> 标签中使用 song.audio 作为 src

目标:

显示带有可播放音频文件的歌曲列表。这是从 admin/ 页面上传的。

我的问题:

当我检查元素时,<source>src 道具似乎成功指向了音频文件,但它并没有将其作为浏览器中的实际可播放“事物”加载。

在 Django runserver 控制台中,单击音频播放器的“播放”按钮时的输出是什么,但是当页面加载时它是"GET /songs/media/song_qW9qTXh.mp3 HTTP/1.1" 404 2715将媒体目录移动到songs/目录中输出还是一样的

Chrome 检查以下代码的输出:

我的东西:

文件夹结构:

song-viewer/
| media/
| | song1.mp3
| | song1_w784FH21.mp3
| | song2.mp3
| | song2_r8JJfq0.mp3
|
| song-viewer/
| | __init__.py
| | settings.py
| | urls.py
| | views.py
|
| songs/
| | migrations/
| | templates/
| | | songs/
| | | | song_list.html
| | __init__.pyt
| | admin.py
| | apps.py
| | forms.py
| | models.py
| | urls.py
| | views.py
|
| static/
| | styles.css
| 
| templates/
| | base_layout.html
|
| manage.py
| README.md
| requirements.txt

歌曲查看器/settings.py:

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static'),
]
STATIC_ROOT = ''

"""
The above static works fine (am able to link CSS successfully).
However, the below does not. I have shotgunned several different
methods of doing this, including setting MEDIA_ROOT = os.path.join(BASE_DIR, ''), and hiding MEDIA_ROOT
"""
MEDIA_ROOT = ''
MEDIA_URL='/media/'

歌曲查看器/urls.py

from django.contrib import admin
from django.urls import path, include
from . import views
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
    path('admin/', admin.site.urls),
    path('songs/', include('songs.urls')),
    path('', views.homepage)
]

urlpatterns += staticfiles_urlpatterns()

song-viewer/views.py

from django.http import HttpResponse
from django.shortcuts import render

def homepage(request):
    # return HttpResponse('Hello from Home!')
    return render(request, 'homepage.html')

歌曲/模板/歌曲/song_list.html

{% extends 'base_layout.html' %}

{% block content %}
    <h1>Song List</h1>
    <div class="songs-container">
        {% for song in songs %}
            <div class="song">
                <h2><a href="{% url 'songs:detail' slug=song.slug %}">{{ song.title }}</a></h2>
                <p>{{ song.snippet }}</p>
                <p>{{ song.date }}</p>
                <audio controls>
                    <source src="{{ song.audio }}" type="audio/mpeg" >
                    <!-- <source src="{{ song.audio }}" type="audio/mpeg" > NOTE: This gives same output--> 
                </audio>
                {{ song.audio }}
            </div>
        {% endfor %}
    </div>
{% endblock %}

歌曲/forms.py

from django import forms

class DocumentForm(forms.Form):
    docfile = forms.FileField(
        label='Select an audio file',
        help_text='Must be mp3 format'
    )

歌曲/models.py

from django.db import models

class Song(models.Model):
    title = models.CharField(max_length=50)
    slug = models.SlugField()
    desc = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    audio = models.FileField(upload_to='media/')

    def __str__(self):
        return self.title

    def snippet(self):
        return self.desc[:50] + ' ...'

歌曲/urls.py

from django.urls import path
from . import views

app_name = 'songs'

urlpatterns = [
    path('', views.song_list, name="list"),
    path('<slug>/', views.song_detail, name="detail")
]

歌曲/views.py

from django.shortcuts import render

from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse

from .models import Song
from .forms import DocumentForm


def song_list(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Song(docfile = request.FILES['docfile'])
            newdoc.save()

            return HttpResponseRedirect(reverse('song_list'))
    else:
        form = DocumentForm()

    songs_data = Song.objects.all().order_by('date')
    return render(request, 'songs/song_list.html', {'songs': songs_data, 'form': form})

def song_detail(request, slug):
    return HttpResponse(slug)

【问题讨论】:

  • 浏览器是否在页面加载时抛出错误/警告。您发布的代码看起来不错。
  • @t.stv 浏览器控制台中的唯一错误是GET http://127.0.0.1:8000/songs/media/song_qW9qTXh.mp3 404 (Not Found),它与 Django 运行服务器输出相同。无论媒体文件夹是否在歌曲/目录中,此消息也是相同的
  • 尝试将 {{song.audio}} 替换为 {{song.audio.url}}
  • 相同的结果 GET http://127.0.0.1:8000/songs/media/song_qW9qTXh.mp3 404 (Not Found) 无论媒体/是否在歌曲中/
  • 您是否按照 Black-Xstar 下面的建议添加了 media_url 和 media_root?

标签: python django audio django-forms


【解决方案1】:

我假设您正在开发服务器上运行。您可以使用 django.views.static.serve() 视图从 MEDIA_ROOT 提供媒体文件。

song-viewer/settings.py

MEDIA_ROOT = os.path.join(BASE_DIR, '')
MEDIA_URL = '/media/'

歌曲查看器/urls.py

from django.contrib import admin
from django.urls import path, include
from . import views
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('songs/', include('songs.urls')),
    path('', views.homepage)
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urlpatterns += staticfiles_urlpatterns()

参考:https://docs.djangoproject.com/en/2.2/howto/static-files/#serving-files-uploaded-by-a-user-during-development

【讨论】:

  • 使用MEDIA_ROOT='/media/'MEDIA_URL='',该代码块在第12 行抛出Empty static prefix not permitted。我错过了什么吗?
  • @bananabrann 尝试:MEDIA_ROOT = os.path.join(BASE_DIR, 'media')MEDIA_URL = '/media/'
  • 哦,好吧,这至少改变了 Django 中的控制台输出。使用MEDIA_ROOT = os.path.join(BASE_DIR, 'media')MEDIA_URL='',它会在第12 行抛出“不允许使用空静态前缀”。使用MEDIA_URL='/media/',它会加载页面,但控制台输出是"GET /media/media/song_qW9qTXh.mp3 HTTP/1.1" 404 1833
  • 但是,添加一个文件夹 media/,(所以路径是 media/media/song_fji44f8)它确实加载!但它在哪里抓住了第二个“媒体”?
  • 我没有看到你的完整代码,或者我只是错过了一些东西。我可以稍后再回去检查。但我很高兴它正在工作。我现在根据您的评论修改了我的答案。
猜你喜欢
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 2016-04-03
  • 2016-02-18
  • 1970-01-01
  • 2020-07-30
  • 2022-01-21
相关资源
最近更新 更多