Upload a file in admin and then download from the website Django - 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>

Related

How to generate link for file download?

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.

can't get image to load

I probably did something stupid but when i upload a image with /admin I can't get it to load.
I made a for loop to get all post's and everything shows except for the image
model:
`class Post(models.Model):
title = models.CharField(max_length=140)
body = models.TextField()
image = models.ImageField(upload_to='blog/media/photos')
date = models.DateTimeField()`
template page:
` {% for post in object_list %}
<h5>{{post.title}}</h5>
<img src="{{ post.image.url }}">
<h1>{{ post.image.url }}</h1>
{% endfor %}`
I would imagine it is related to your MEDIA_URL settings. Check the terminal output and look for the request to the image, there is a good chance you've not set that, and/or you've not added the media url handler to your urls.
https://docs.djangoproject.com/en/2.0/howto/static-files/#serving-files-uploaded-by-a-user-during-development
You must set the media folder path in the settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
or add media root on url.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Is there a blog/media/photos folder path and accessable?

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 imageField url on html

I've this hiearchy:
-mega_series
-mega_series
-series
-models.py
-views.py
...
-manage.py
-media
-covers
-static
The MEDIA_URL AND MEDIA_ROOT are the following:
MEDIA_ROOT = '/Users/lechucico/Documents/mega_series/media/'
MEDIA_URL = 'media/'
On the model I store the image like that:
class Serie (models.Model):
serie_cover = models.ImageField(upload_to='covers')
serie_name = models.CharField(max_length=100)
The images once uploaded via admin site goes correctly to path: mega_series/media/covers/
And this is how I acces it via html:
<img src="{{serie.serie_cover.url}}" width="150" height="250" />
The result url that I got is the following:
http://127.0.0.1:8000/media/covers/juego_de_tronos.jpg
Why the image doesn't appear on the html?
Thanks.
You would need to define MEDIA_ROOT as mentioned here
From Django officaal Docs:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
You can also have a look at this.

How to add a file from a filefield in Django to urls and views?

I'm doing a Django project, and I have a model called Projects, in this model I have a FileField inwhich files get uploaded to /media/files/YEAR/MONTH/DATE/.
settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models.py:
class Project(models.Model):
...
file_upload = models.FileField(upload_to='files/%Y/%m/%d', max_length=100, null=True, blank=True, default='')
template:
...
{% if project.file_upload %}
<tr>
<td>File</td>
<td>{{ project.file_upload.name }} (Size: {{ project.file_upload.size|filesizeformat }})</td>
</tr>
{% endif %}
...
Now a link to a file would be something like: /media/files/2016/05/25/picture.png or /media/files/2016/05/25/report.pdf
Currently I get a 404 page not found, whenever I click the link. That is ofcourse because the path is not in the urls.py, but since you usually add a view to an url, I don't know how you would do it with a single file, as it would seem to me a view wouldn't be necessary.
How do I tell Django in urls (And possibly in views) how to get that file? I want to be able to click the link and then either view the picture/pdf in the browser or simply download the file.
Django does not serve static files. To force these files to be served when DEBUG=True, add this code to urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
(from https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-static-files-during-development)
You do not need to tell Django about static files in views.py