I've just started out with Django and have tried making an audio player application website. I (admin) want to be able to upload audio files that visitors can listen to.
I've created a model for succesfully uploading a file, taking a input file name, and storing it in a media folder in within my app directory:
class Song(models.Model):
name = models.CharField(max_length=125)
audio_file = models.FileField(upload_to='audio_player/media/audio_player/')
def __str__(self):
return self.name
In my Template I then have a for loop set up to create list of audio players for every different audio track.:
<div class="container">
{% for song in songs %}
<audio controls id="player">
<source src="{{ song.audio_file.url }}" type="audio/wav">
</audio>
{% endfor %}
</div>
Now this is where I've gotten stuck. The audio player appears accordingly, but you cannot play any audio. I've tried to check via Chromes DevTools and there the source, or src, is the correct file path to the files.
<source src="audio_player/media/audio_player/Song.wav" type="audio/wav">
I've been going crazy for the last day or so trying to figure out what is causing it not to work. I spent a lot of time trying to get it to source the correct path for the files but even though it seems to do that the files still can't be played.
I suspect that it could have something to to with passing the files into the template, from what I understand you should be able to pass a file as context right?
This is how my views are set up:
def ap(request):
context = {
"songs": Song.objects.all(),
}
return render(request, "audio_player/home.html",context)
Thankful for any help I can receive! Sorry for any eventual formatting errors and such...
Got it to work by setting these in settings.py
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
...and by adding this to my urls.py
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
...as well as changing my FileField Upload to
upload_to="audio_player/"
(Pretty much, just looking at the Django official docs again but being aware that I was not understanding things correctly and pretty much copying what it said straight up worked)
<div class="container">
{% for song in songs %}
<audio controls id="player">
<source src="{% if song.audio_file %}{{ song.audio_file.url }}{% endif %}" type="audio/wav">
</audio>
{% endfor %}
</div>
Related
I'm looking to display an uploaded .html file in an iFrame on my template. I would rather NOT set it up as a url to visit in the urls.py file, I upload .html files from the admin panel to the media folder like so:
model
# Portfolio project overview model
class Work(models.Model):
html = models.FileField(upload_to="work_app/media/htmls/", null=True, blank=True)
settings.py
MEDIA_ROOT = str(BASE_DIR) + "/media/"
MEDIA_URL = '/media/'
STATIC_ROOT = str(BASE_DIR) + "/static/"
STATIC_URL = '/static/'
urls.py
urlpatterns = [
include("personal_portfolio_project.apps.resume_app.urls")),
path("work/", include("personal_portfolio_project.apps.work_app.urls")),
]
if DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My first attempt to display it using this template.html code:
{% extends "base.html" %}
{% load static %}
{% block page_content %}
<h1>{{ work.title }}</h1>
<div class="row">
<div class="col-md-8">
{% if work.html %}
<iframe height="100%" width="100%" src="{{ 'work.html.url' }}">
</iframe>
{% endif %}
</div>
</div>
{% endblock %}
...looks like this:
As you can see, the iFrame is displaying, but seems like it can't find the .html file (404).
I saw in a few other posts that the html line should be:
<iframe height="100%" width="100%" src="{% url 'work.html' %}"> </iframe>
..and to also add X_FRAME_OPTIONS = 'SAMEORIGIN' to your settings.py file, so I did both those, where I now get:
What is this trying to tell me? What am I missing?
UPDATE
I have also tried:
<iframe height="100%" width="100%" src="{{ work.html }}"> </iframe>
to which I get another 404:
UPDATE
The closest I've gotten is using this:
<iframe type="html" height="100%" width="100%" src="{{ work.html.url }}"> </iframe>
But it gives me this screen:
I put the url above the image to make sure that it is in fact correct. According to other answers, they said just to enable X_FRAME_OPTIONS = 'SAMEORIGIN' and it'll work, but it doesn't for me. Any help from here would be greatly appreciated. Thanks!
I take back my last UPDATE above, what I had to do was clear my cache, or run the page in incognito mode as none of my changes were being reflected on the page due to the cache. Once I did that, it started showing the iframe properly.
Another option I was exploring was to set an xframe exemption decorator to the view that handles rendering the post details page, which would look something like:
from django.shortcuts import render
from django.views.decorators.clickjacking import xframe_options_exempt
# Create your views here.
from .models import Work
#xframe_options_exempt
def work_detail(request, pk):
work = Work.objects.get(pk=pk)
context = {
'work': work
}
return render(request, 'work_detail.html', context)
which also seemed to work, but I'm reverting back to the SAMEORIGIN method.
I have an img folder in the same directory as my html files. I want to put images onto my site but I am doing something wrong.
this is the code:
{% block a %}
<div class="row">
<div class="col-sm-4 center">
<img src="img/img01.jpeg">
</div>
</div>
{% endblock %}
this is what happens when I run the local server.
this is my file directory
Websites generally need to serve additional files such as images, JavaScript, or CSS. In Django, we refer to these files as “static files”.
Those files need to be handled another way as your templates. The documentation can be found here.
It comes basically down to defining a seperate static directory inside your app. It is really good explained in the documentation.
What I want to accomplish is have an separate application generate graphs that will be placed in a directory of my Django project. Then in my template loop through and display all the graphs from that directory on the webpage. The generated graphs will be refreshed daily and will be of varying numbers depending on the day (so some days it could be 20 and/or the next it could be 50).
Option 1)
I don't think I want to use django manage.py collectstatic everyday. I've never gotten to the point of deploying a Django project to a server but my assumption is that I would have to collectstatic manually everyday on the server (which I could be thoroughly off on here)
Option 2)
I've tried creating a model Model Picture. The Char field is just my relative path to the picture. From there in my views I'm to rendering the path in the index(request) View Picture. From there in my template I'm trying to loop through the picture relative paths and show them Template Picture. When I remove photos = Photo.objects.all() & the {% for img in photos %} in the template the page does load Webpage working. However when I run it with all those parts in there I get a blank webpage with "what do you want to do with index" at the bottom. Webpage not working
Interested to hear if there are any better way of doing this . I'm not trying to user upload an image field because the amount of graphs will be substantial.
Details on Option 2:
---Notes---
Top Lvl Directory is--chartingtest-project
chartingtest is the project
sectors is the name of the app
media folder is a folder in the top level directory, not within the project or test folder
models.py in sectors app contains
class Photo(models.Model):
photoname = models.ImageField()
views.py in sectors app contains
from .models import Photo
def index(request):
pets = Pets.objects.all()
photos = Photo.objects.all()
return render(request, 'index.html', {'pets': pets}, {'photos': photos})
index.html template
{% load static %}
<H1>Hello World Index!</H1>
#Testing bringing in variables from a model (2020/05/07 Works!)
<ul>
{% for pet in pets %}
<li>{{pet.name}}</li>
{% endfor %}
</ul>
# ************************************
# This is where I'm trying display generated pictures from the media folder
# ************************************
<ul>
{% for img in photos %}
<li>
<img src="chart1s/{{img.image.url}}" />
</li>
{% endfor %}
</ul>
#Testing Static Image (2020/05/08 Works!)
<img src="{% static "OIP.jpg" %}"/>
<img src="{% static "temp_fig_00.png" %}"/>
settings.py in chartingtest project folder
#Media ROOT
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
You are correct that using static files will not work, by their name static files are not supposed to change.
The solution is to create a media folder and have your application save the graphs to that folder. Your model picture should point to that folder. Like you said, in your templates you can then iterate over that model to display all the graphs.
In production, you should create a cloud storage bucket and save your images there. Then make sure your settings.py directs any requests for images to your storage bucket.
Your picture model should use models.ImageField(), not a typical CharField, image = models.ImageField(). In your template as you iterate, you should call each image with <img src="{{ picture.image.url }}"
Apart from that, I would need to look in depth at the code to see what's going on, and I don't click links on stackoverflow posts. If you'd post the code in a comment might be able to take a closer link, but try those things first!
I'm using auto generated HTML which has been saved to a file and then read in again to use as part of a page in a django template.
In order to do this I have used:
{% autoescape off %}
{{ my_html }}
{% endautoescape %}
However, in the my_html variable, I have some static content. This comes in the form of something like this:
<img src="{% static "img/tree_report.png" %}" width="12px" height="12px"/>
My issue is that the static content is not displayed. I get:
http://127.0.0.1:8000/%7B%%20static 404 (in the browser error report)
I read something about get_static_prefix in another question but that doesn't solve my problem because I just get this instead:
GET http://127.0.0.1:8000/%7B%%20get_static_prefix%20%%7Dimg/tree_report.png 404 (Not Found)
I also tried endautoscape turning on and off periodically in my_html in the saved HTML variable. That also didn't work.
Should I be autogenerating the development and production static files paths for my_html or is there a more elegant solution to this problem?
Any suggestions are most welcome.
Thanks.
How do i use the audio tag of html 5 to play a audio file that has been uploaded in a my django based application.
models.py - Link
settings.py - Link
In my templates i am using the audio tag in the following way -
{% for file in audio %}
<li>
<h4>{{ file.title }}</h4>
<div id="name">{{ file.name }}</div>
<div id="play"><audio src="{{ file.audio_file }}" controls="controls">
Your browser does not support the audio element.
</audio></div>
</li>
{% endfor %}
But I am not able to play the file.
Based on your settings, you cannot play the file because:
{{ file.audio_file }} returns value saved in the database, which is absolute path to media file, e.g. http://localhost:8000/Users/test/django_app/media/test.wav
To solve this, you need to:
Edit your models.py
class AudioFile(models.Model):
audio_file = models.FileField(upload_to="music")
upload_to -- A path that will be appended to your MEDIA_ROOT setting to determine the value of the url attribute
In your template, use {{ file.audio_file.url }} to correctly reference the URL of the uploaded file
You may need to delete existing files, because wrong path was saved in the database.