Django - Serving user uploaded media files - django

I'm trying to display the media file(image) on the template of a DetailView.
I ran print statements to check where the MEDIA_ROOT and MEDIAFILES_DIRS are pointing, and they both point correctly to /project/static/media.
So I try to call it on the html page by using <img src="{{ object.profile_pic.url }}" /> , but it's not displaying.
I check the console, and it is looking for the file in XXX.X.X.X:8000/media/image_file.jpg.
Is it something to do with my MEDIA FILES setup in settings.py?
This is how my folder structure looks
/project
/project
/project
urls.py (base)
/apps
/app1
urls.py
manage.py
/static
/media
image_file.jpg
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__)))
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(os.path.dirname(BASE_DIR), "static", "static_files"),
]
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static", "static_root")
"""
MEDIA FILES
"""
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static", "media")
MEDIAFILES_DIRS = [
os.path.join(os.path.dirname(BASE_DIR), "static", "media"),
]
"""
Override the BaseUser model
"""
AUTH_USER_MODEL = 'accounts.User'
urls.py
// need to add the +static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) to the base urls.py, not the app-level
from django.conf.urls import include, url
from django.contrib import admin
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', views.HomepageTemplateView.as_view(), name='home'),
url(r'^how-it-works/$', views.HowItWorksTemplateView.as_view(), name='how-it-works'),
url(r'^categories/', include('apps.categories.urls')),
url(r'^tasks/', include('apps.tasks.urls')),
url(r'^accounts/', include('apps.accounts.urls')),
url(r'^admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
detailview.html
{% extends 'base.html' %}
{% block navbar %}
<div class="row">
<div class="container">
{% include 'navbar.html' %}
</div>
</div>
{% endblock %}
{% block content %}
<div class="row">
<div class="container">
<div class="col-md-12">
{% load staticfiles %}
<p><img src="{{ object.profile_pic.url }}" /></p>
<p>{{ object.username }}</p>
<p>{{ object.first_name }} {{ object.last_name }}</p>
<p>{{ object.email }}</p>
<p>{{ object.contractorprofile.subcategory }}</p>
</div>
</div>
</div>
{% endblock %}

You added the static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) line to the urls.py of a specific app, i.e. not the base level urls.py. The base level will include the app-specific urls appending them to some stem. If the base urls.py has something like this, url(r'^apps/', include('apps.app1.urls')), then point your browser to server:8000/apps/media/image_file.jpg.
That's not what you want, so move the static() MEDIA_URL call to the base, project-level urls.py.
Let me mention a couple other things. Your folder structure puts media/ under static/; that's pretty confusing. You also included the settings for STATIC and MEDIA. Static files and media files are completely separate (often mixed up) topics. Static files are used by your code. Static files are the CSS, JavaScript, images, etc that your application needs. Media files are assets—images, documents, etc—that accrue through use of the application. profile_pic in your case is a perfect example of media; it's something a user uploaded. So nesting your media directory under static/ is conflating two independent things. Don't do it.
Another thing, you don't need {% load staticfiles %} in the template. That's used for staticfile-provided templatetags like {% static ...%} which you aren't using. Anyway, you should load templatetags at the top of the file to keep things clean.

Related

Django is loading static files but not image that are stored from backend in production

As the title says, after I changed DEBUG to False, the image that is uploaded from the admin panel are not loading. However, other static files like css files and images that are loaded only from HTML side are rendered properly.
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('marathon.urls', namespace='homepage')),
path('accounts/', include('allauth.urls')),
path('logout', LogoutView.as_view(), name='logout'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
html file that renders image
<div class="js-billboard">
{% for slide in slider %}
<div class="billboard__item">
<figure><img src="{{ slide.image.url }}" alt="Mountain Marathon"></figure>
<div class="billboard__detail">
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="col-12 cell">
<h2>{{ slide.title }}</h2>
<p><span>{{ slide.description }}</span></p>
{{ slide.link_title }}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
I assume you have the following line of code in your projects urls.py
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Please note that static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) for your media urls will only be added to your urlpatterns list if DEBUG=True in this case. Django doesn't serve media files in Production or when the DEBUG=False
I would suggest using a online storage API like AWS3, cloudinary or even firebase. These do offer the capability of serving media files whether DEBUG=True or DEBUG=False.
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
add this in your main your urls.py folder and create a forlder name staic cdn in you main project and in your settings.py
STATIC_CDN = BASE_DIR / 'static_cdn'
and in bottom
STATIC_ROOT = STATIC_CDN
# MEDIA
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
and then run
python manage.py collectstatic
in your terminal what it will do it will create copy of you static file in your static cdn folder because cloud base storage look your static or media file in you cdn folder
and make sure you install pillow
and tell me if you still getting error

Media Files not Loading on pythonanywhere.com (Django)

website: https://willpeoples1.pythonanywhere.com/
I deployed a personal portfolio project using pythonanywhere.com's server and my instructor sent me a video explaining why my media files weren't loading properly (https://d.pr/v/RARFcF). However, I couldn't understand why he was telling me to change the pathname of the image in my HTML b/c I am using a template in the img-tag. Any clue where I should go from here? Thanks
settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URLS = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
from portfolio import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('blog/', include('blog.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
home page HTML file:
<div class="conatainer text-center">
{% for proj in Projects %}
<hr>
<h2>{{ proj.title }}</h2>
<p>{{ proj.description }}</p>
<img src= "{{ proj.image.url }}" target="_blank" height="300" width="300">
<br>
<br>
{% endfor %}
</div>
This is all set. There was a spelling mistake in my settings.py file. I wrote "MEDIA_URLS" instead of "MEDIA_URL".

Not able to display image in django

files of whole project
I have correctly setup path for media url and still not able to find images in allproducts.html where as in categories.html it is able to find images from media directory. I am not able understand the cause of this bug.
allproducts.html
{% for sub in subcategory %}
{% for p in sub.product_set.all %}
<div class="product">
<div><h3 class="logo header_content d-flex flex-row align-items-center justify-content-start">{{sub.name}}</h3></div>
<div class="product_image"><img src="media/{{p.image}}" alt=""></div>
<div class="product_content">
<div class="product_title">{{p.name}}</div>
<div class="product_price">{{p.price}}</div>
</div>
</div>
{% endfor %}
<div></div>
{% endfor %}
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
STATIC_DIR,
]
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
urls.py
urlpatterns = [
path('',views.index, name="index"),
path('cart',views.cart, name="cart"),
path('categories',views.categories, name="categories"),
path('checkout',views.checkout, name="checkout"),
path('contact',views.contact, name="contact"),
path('product/<int:pk>/',views.product, name="product"),
path('allproducts/<int:pk>/', views.allproducts, name="allproduct"),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
def allproducts(request, pk):
products = Product.objects.all()
category = Category.objects.get(pk=pk)
subcategory = Subcategory.objects.filter(category = category)
return render(request, 'shop/allproducts.html',
{'products':products, 'subcategory':subcategory,
'category':category})
project files
kh
kh
.idea
__init__.py
settings.py
urls.py
wsgi.py
media
shop
images
test.jpg
shop
db.sqlite3
manage.py
You will certainly need a leading slash:
<img src="/media/{{p.image}}" alt="">
But better to let the image itself output its full path:
<img src="{{p.image.url}}" alt="">

how to load media from another app django

I have two apps accounts and home in tutorial project.
A user can create a post in home app and I'm able to render post(i.e images and post data) in home app. In accounts app I want to create a search page where not logged in user can search and view the posts.
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'tutorial/media/')
search.html
{% load static %}
{% if re %}
{% for q in re %}
<a href="{% url 'home:Post_detail' pk=q.id %}">{{q.id}}.{{ q.post }}
<br>
<img src="{{ q.image.url}}" width="240" height="auto">
<p>Posted by {{ q.user.get_full_name }} on {{ q.created }}</p>
{%endfor%}
{% endif %}
I use the above code in both home app and accounts app. It works fine for home app but not for accounts app
when I see view source page I get perfect url in accounts app (search.html) but, the images are not loading properly screenshot
project urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('accounts/', include('accounts.urls' , namespace='accounts') ),
path('home/', include('home.urls' , namespace='home') ),
path('admin/', admin.site.urls),
path('',login_redirect , name = 'login_redirect'),
]
if settings.DEBUG is True:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
tutorial project structure
tutorial
|_accounts
|_home
|_tutorial
|_media
|_profile_images
|_all image files

Django 1.9: Unable to see uploaded photos

I have some photos uploaded but I was unable to see photos in temeplates
My template
{% extends 'base.html' %}
{% load staticfiles %}
{% block content %}
<div class="row ">
<div class="col-md-8">
<h1>{{ object.title }}</h1>
{% if object.productimage_set.count > 0 %}
<div>
{% for img in object.productimage_set.all %}
{{ img.image.file }}
{{ img.image.url }}
<img class='img-responsive' src='{{ img.image.url }}' />
</div>
{% endfor %}
</div>
{% endif %}
<div class="lead">{{ object.description }}</div>
</div>
</div>
My model
class Product(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(decimal_places=2, max_digits=20)
active = models.BooleanField(default=True)
def __unicode__(self): # def __str__(self):
return self.title
class ProductImage(models.Model):
product = models.ForeignKey(Product)
image = models.ImageField(upload_to='product/')
Setting for media
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static", "my_static"),
]
STATIC_ROOT = os.path.join(BASE_DIR, "static", "static_root")
STATIC_URL = '/media/media_root/'
MEDIA_ROOT = os.path.join(BASE_DIR, "static", "media_root")
My urls
urlpatterns = [
url(r'^contact/', views.contact, name='contact'),
url(r'^$', views.ProductViewList.as_view(), name='ProductViewList'),
url(r'^(?P<pk>\d+)/$', views.ProductDetailView.as_view(), name='Product_Detail'),]
My folder structure
In the template {{ img.image.url }} gives -> product/mp3.jpg. But still I'm unable to see the image
The console shows that image is loaded from http://127.0.0.1:8080/product/1/product/mp3.jpg I guess there is some prob with the url to collect the image but not sure
Any help is much appreciated....Thanks in advance
You should add the MEDIA_URL to your settings.py, if you haven't.
In your case, the MEDIA_URL should be media_root. My Image links all have /media/....jpg.
In addition, you can specify the URLs:
from django.conf import settings
if settings.DEBUG:
# static files (images, css, javascript, etc.)
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT}))
Here's some documentation from Django on this: https://docs.djangoproject.com/en/1.9/howto/static-files/#serving-files-uploaded-by-a-user-during-development
I prefer keeping my media files separate from my static files, so during development I actually store mine in the project root. The following snippets use the project root as the media location, but you can easily adjust this by changing it to static/media_root if you'd prefer to keep your current location.
First make sure you've defined your media root in your settings.py file:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Then try adding the following to your project's urls.py file:
from django.conf import settings
if settings.DEBUG:
urlpatterns += patterns('', (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}))