How to generate link for file download? - django

I created a model without using FileField() and saved the url into path field. Now while displaying I can see the attributes but I cannot download the file. href treats it as a page and i get an error saying GET request failed.
I need to do the same for static files also.
models.py looks like this:
import os
from django.conf import settings
from django.db import models
# Create your models here.
class Document(models.Model):
code = models.CharField(max_length = 50)
path = models.CharField(max_length = 500)
date_of_submission = models.CharField(max_length = 50)
type = models.CharField(max_length = 50)
title = models.CharField(max_length = 200)
department = models.CharField(max_length = 50)
subject = models.CharField(max_length = 100)
updation_allowed = models.CharField(max_length = 1, default = '0')
#property
def relative_path(self):
return os.path.relpath(self.path, settings.MEDIA_ROOT)
template has some code like this:
<a href = '{{ MEDIA_URL }}{{ value.thesis.relative_path }}'> Thesis </a>
*static files*
<a href='/uploads/report.pdf'> Front Page</a>
I tried using the property and provinding the path myself.

urls.py (project/urls.py)
from django.conf.urls.static import static
urlpatterns = [
...
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
...
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

To allow file downloading you need to create a separate view with FileResponse as a response. This view will take some unique argument (I suppose it will be relative path to the file) with url provided in html template. Inside this view, FileResponse will open your file by provided path and then will return response with your file. I think you should do it like this:
Views.py:
def download_file(request, relative_path): # this is a view with file response
media_root = settings.MEDIA_ROOT
return FileResponse(open(f"{media_root}\{relative_path}", "rb"), as_attachment=True, filename="some_name.smth")
template:
<a href = '{% url "download" relative_path=value.thesis.relative_path %}'> Thesis </a>
*static files*
<a href='/uploads/report.pdf'> Front Page</a>
urls.py:
urlpatterns = [
path("download-file/<slug:relative_path>/", views.download_file, name="download")]
You will need to combine with PATHes to get it to work.

Related

Upload a file in admin and then download from the website Django

I am trying to create a website, where customer can upload a file in an Admin section, and after any person can download this file from the website. Preferably any files like pdf, exe, doc (is it possible?) I am able to upload a file in Admin and it shows it on the website. It downloads the file with a correct name (saved in media) but shows a failure , file missing.
So far I have :
setting.py
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models.py
class TEACHING(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(auto_now_add=True)
excercise = models.FileField(upload_to="files/", default='default value')
def __str__(self):
return self.title
views.py
def teaching(request):
context = { 'teaches' : TEACHING.objects.all()}
return render(request, 'blog/teaching.html', context)
urls.py
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
teaching.html
{% for teach in teaches %}
<a href="{{ teach.excercise }}" download>Download</a>
{% endfor %}
Managing files docs
You should get URL from your File field
<a href="{{ teach.excercise.url }}" download>Download</a>
Hi You are not providing url in href, so please change your <a> with following way
<a href="{{ teach.excercise.url }}" download>Download</a>

Why cannot I see the image file in django?

I tried to load an image file, but it didn't work. I uploaded the image file by admin. Thanks for the help!
here is my code
in urls.py
path('main/archive/<int:video_id>/', views.loadphoto, name='loadphoto'),
in views.py
def loadphoto(request, video_id):
target_img=get_object_or_404(Record, pk=video_id)
context={'target_img':target_img.picture}
in models.py
class Record(models.Model):
record_text = models.CharField(max_length=50)
pub_date = models.DateTimeField('date published')
picture=models.ImageField(blank=True)
def __str__(self):
return self.record_text
in img.html
<img src="target_img">
Main
First You Need To Join Your Media directory to your app
Here is the Way You Can Do That:
First You Need To Add This in Your Setting.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASEDIR,'your folder directory')
#for example app/media or something
Then You Need To Create Media Url Here is The Way:
Then You Need To Add in your urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('main/archive/<int:video_id>/', views.loadphoto,name='loadphoto'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Then You Need To Add This in Your Html File
<img src='{{ target_img.url }}'>
You Can See More Details Here:
https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.fields.files.FieldFile.url
ImageField is derived from FileField. In order to display the image in your template, you should provide its url, see https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.fields.files.FieldFile.url
The source attribute should instead by populated as follow:
<img src="target_img.url">

Images not loading Django website

Images on my django website are not loading for some reason
This is my models.py
thumbnail = models.ImageField(upload_to='images/',blank=True)
This is my settings.py lines
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
if DEBUG:
STATIC_ROOT = os.path.join(BASE_DIR, 'static/static-only')
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/static'),
)
This is my views.py
class BlogIndex(generic.ListView):
queryset = models.Entry.objects.published()
template_name = "index.html"
paginate_by = 5
In url.py
if settings.DEBUG:
urlpatterns +=static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
In index.html i did this
<img class="img-rounded" src = "{{object.thumbnail.url}}"/>
pip freeze
Django==1.11.2
django-ckeditor==5.2.2
django-crispy-forms==1.6.1
django-markdown==0.8.4
django-pagedown==0.1.3
Markdown==2.6.8
olefile==0.44
Pillow==4.1.1
The Images are getting saved in the static/media/images directory
But the images are not loading in the web page...
When i try to right-click and view the image It shows this error SCREEN SHOT
Other objects are working perfectly.. Only the images aren't loading
You need the media url in the src:
<img class="img-rounded" src = "{{object.thumbnail.url}}"/>
should be:
<img class="img-rounded" src = "{{MEDIA_URL}}{{object.thumbnail.url}}"/>
or something similar
<img class="img-rounded" src = "/static/media/uploads/{{object.thumbnail.url}}"/>
The Issue is fixed, (Got assistance from a facebook group)
The issue was a url pattern in the views.py
The screen shot that I put had a line
Raised by : blog.views.Blogdetail
Apparently i had a urlpattern
url(r'^(?P<slug>\S+)/$', views.BlogDetail.as_view(), name='entry_detail'),
My pattern for blog detail view has match \S+ - so any string of characters that has no spaces in
Which will match pretty much any pattern that hasn't matched previously and any other url pattern which are below this particular url will not be accessed
Changed the url pattern to the following and I was good to go
url(r'^(?P<slug>[-\w]+)/$', views.BlogDetail.as_view(),name='entry_detail'),
settings.py:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
in this model you can see Overwrite of exist IMG, return img as base string:
models.py
from django.db import models
from django.core.files.storage import FileSystemStorage
from base64 import b64encode, b64decode
class OverwriteStorage(FileSystemStorage):
def get_available_name(self, name, max_length=700):
if self.exists(name):
os.remove(os.path.join(settings.MEDIA_ROOT, name))
return name
def upload_location(instance, filename):
return os.path.join('defaultfolder', instance.phone, filename)
class ImgModel(models.Model):
name= models.CharField(max_length=100)
img = models.FileField(storage=OverwriteStorage(),
upload_to=phone_upload_location,
null=True,
blank=True,
max_length=700)
def image_to_base64(self, model_picture_path):
if model_picture_path:
try:
with open(model_picture_path.path, "rb") as imageFile:
str = b64encode(imageFile.read())
return "data:image/jpg;base64,%s" % str.decode()
except IOError:
return model_picture_path.url
else:
return None
.html
<img src="{{ MEDIA_URL }}foo.jpg">
I faced this issue and I tried lot of things but imges wont load then I tried out a simple trick but this did the job. What I did was, in my settings.py file, I included the STATIC_DIR varaible just after BASE_DIR. Below is my settings.py file
Settings.py
#Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIR=os.path.join(BASE_DIR,'templates')
STATIC_DIR=os.path.join(BASE_DIR,"static")
#Other content
STATIC_URL = '/static/'
STATICFILES_DIRS=(
STATIC_DIR,
)
Check this out maybe this will help!
How to fix images answer is
mention above index.html
{% static 'travello/images/' as baseUrl %}
path
then

Django video in template, seems to detect media but not working

Please i have been working on this for a while but don't seem to find the problem. I am trying to get a video from the uploaded files to work on the template,but all i keep getting is a blank video, although when i view the page source or inspect the video element, it seems to be pointing to the right video, and all solutions i have tried to make this work proved abortive.
Below are my codes:
MY MODEL:
class Sermon(models.Model):
topic = models.CharField('Topic', max_length=50)
pub_date = models.DateField('Sermon Date')
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
last_edited = models.DateTimeField(auto_now_add=False, auto_now=True)
type = models.CharField('Type', max_length=50, choices=sermon_chioices)
audio = models.FileField(upload_to='audios', default="Not Available", blank=True, validators=[validate_audio_extension], null=True)
video = models.FileField(upload_to='videos', default="Not Available", blank=True)#can be changed if the video will recide in the system
outlines = models.FileField(upload_to="outlines", default="Not Available", blank=True,)
user = models.ForeignKey(User, verbose_name="User", editable=False)
class Meta:
ordering = ['-pub_date']
def __unicode__(self):
return self.topic
def get_absolute_url(self):
#return reverse('sermon_detail', kwargs={'pk': self.pk})
return reverse('sermon_detail', args=[str(self.id)])
MY VIEW:
class SermonDetails(DetailView):
model = Sermon
template_name = 'agonopa/sermon_details.html'
context_object_name = 'sermon'
def get_context_data(self, **kwargs):
context = super(SermonDetails, self).get_context_data(**kwargs)
#context['sermons'] = Sermon.objects.all()
return context
#Sunday Service List
class SundayServiceSermonList(ListView):
model = Sermon
template_name = 'agonopa/sermon.html'
context_object_name = 'sermon_list' #'ss_sermon_list'
queryset = Sermon.objects.filter(type__exact="SUNDAY SERVICE")
def get_context_data(self, **kwargs):
context = super(SundayServiceSermonList, self).get_context_data(**kwargs)
context['title'] = 'Sunday Service'
return context
MY TEMPLATE:
{% if sermon %}
<h3>{{ sermon.topic}}</h3>
{{sermon.outline}}
{{ sermon.pub_date}}
{% endif %}
<video loop class="embed-responsive-item thumbnails" controls>
<source src="{{ MEDIA_URL}}{{sermon.video.url}}" type="video/mp4">
</video>
MY MEDIA SETTINGS:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(BASE_DIR)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(PROJECT_DIR,'churchsite_static_root','media_root')
The Server returns things like this in the terminal:
[28/Nov/2015 11:38:10]"GET /agonopa/sermon/3/ HTTP/1.1" 200 377
[28/Nov/2015 11:38:10]"GET /media/videos/wowo_Boyz_5gQAbzG.mp4 HTTP/1.1" 404 2344
Thanks for your help in advance, and for further clarification on the question pls do let me know.
It should be noted, that i have tried many solutions from stakeoverflow, and several blogs but none seems to works, so i had to post it here.
It seems to me that your MEDIA_ROOT is way too high (as in no longer within your project). When I use the settings you use, I get a media root directory of ../../../churchsite_static_root/media_root/ relative to your settings.py file. I would expect churchsite_static_root to be one directory up from settings.py (or at the same level as manage.py).
Go into Django shell and check the media root path to see if it seems reasonable (and confirm that your files are actually there):
python manage.py shell
>>> from django.conf import settings
>>> settings.MEDIA_ROOT
Try the following in your settings.py and let me know if it helps:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, 'churchsite_static_root', 'media_root')
Be sure you have something like this in your site's urls.py if using python manage.py runserver:
# For Django>=1.8:
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# For Django<1.8:
if settings.DEBUG:
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
I simply imported settings, and then static, and also added the if Debug: to my urls.py, thus the program looked as below:
Urls.py:
from django.conf.urls import include, url, patterns
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from agonopa.views import SermonMonthArchiveView, SermonYearArchiveView
urlpatterns = [
# Examples:
# url(r'^$', 'churchsite.views.home', name='home'),
url(r'^$', 'agonopa.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^agonopa/', include('agonopa.urls')),
url(r'^grappelli/', include('grappelli.urls')),
url(r'^admin/', include(admin.site.urls)),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
That's all to it. Thanks to Mike Covington in all.
Also note, that the media settings, template and other files above didn't change for the whole stuff to work.

Django images not displaying

I am trying to give the users the ability to upload profile pictures and I have the Upload section working. Im running into issues when trying to display the picture in the template. Here is what I currently have:
Urls.py:
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.ME DIA_ROOT,}),
#other urls
);
Settings.py:
MEDIA_ROOT = '/home/bpurdy/socialCompromise/media/'
MEDIA_URL = '/media/'
Model:
class Member(models.Model):
STATUS = Choices('active', 'disabled')
GENDER_CHOICES = (('Male','M'), ('Female','F'),)
user = models.ForeignKey(User)
created_date = models.DateTimeField(auto_now_add = True)
updated_date = models.DateTimeField(auto_now = True)
photo = models.ImageField("Profile Pic", upload_to="images/profiles", blank = True, null = True)
#Other user properties
Template: (Key is the user)
{%if key.profile.photo %}
<img src="{{ key.profile.photo.url }}" alt="{{key.profile.photo.title}}">
{%endif%}
After the upload there is a file located in the /home/bpurdy/socialCompromise/media/images/profiles directory however when trying to render the page I get the following errors:
SERVER_IP_ADDRESS/media/images/profiles/Desert.jpg 404 (Not Found) And
Resource interpreted as Image but transferred with MIME type text/html: SERVER_IP_ADDRESS/search/images/profiles/Desert.jpg".
And the image wont display.
Try urls.py like this:
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = patterns('',
# urls
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
and tell me how it works.