I've got a problem with displaying images that were uploaded from admin panel. Django renders wrong path, probably due to my configuration mistake somewhere...
This is my model definition:
class Article(models.Model):
"""News article, displayed on homepage to attract users"""
class Meta:
db_table = 'article'
title = models.CharField(max_length=64)
headline = models.CharField(max_length=255)
content = HTMLField()
image = models.ImageField(upload_to = 'articles/', null=True, blank=True)
active = models.BooleanField()
created_at = models.DateTimeField()
def __unicode__(self):
return self.title
This is url configuration:
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# some stuff
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py:
PROJECT_DIR = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(PROJECT_DIR, "media")
MEDIA_URL = '/media/'
the view:
def slider(request):
context = Context ({ 'articles': Article.objects.order_by('-created_at')[:5] })
return render(request, 'articles/slider.html', context)
and the template:
{% for article in articles %}
<img src="{{ article.image.url }}" alt="" />
I would expect django to render http://127.0.0.1:8000/media/articles/slide-02.jpg but now it renders http://127.0.0.1:8000/media/slide-02.jpg. I've defined the upload_to=articles/ in the model class. So why does the article.image.url attribute return a path without this significant directory?
edit: I've got something wrong with my model. It doesn't recognize the upload_to directory:
$ ./manage.py shell
Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from articles.models import Article
>>> Article.objects.all()
[<Article: Blackened Recordings Launches>, <Article: The Rockin' Return of Deep Purple>, <Article: See Emily Day 20th April>, <Article: Celebration Day Premieres In Four Countries Announced>, <Article: Waging heavy innovation>, <Article: Rush to play festival D'Ete, Quebec City>]
>>> Article.objects.all().get(pk=1)
<Article: Blackened Recordings Launches>
>>> Article.objects.all().get(pk=1).image
<ImageFieldFile: slide-03.jpg>
>>> Article.objects.all().get(pk=1).image.path
u'/var/www/django/djninja/djninja/media/slide-03.jpg'
>>> Article.objects.all().get(pk=1).image.url
'/media/slide-03.jpg'
Again, it should be media/articles/slide-03.jpg instead of media/slide-03.jpg. So I guess all routing/template is ok, something's wrong with the model.
In views.py:
from django.shortcuts import render_to_response, RequestContext
def slider(request):
articles = Article.objects.order_by('-created_at')[:5]
return render_to_response('articles/slider.html', locals(), context_instance = RequestContext(request)
In slider.html:
{% for article in articles %}
<img src="{{ MEDIA_URL }}{{ article.image.url }}" alt="" />
{% endfor %}
In urls.py:
from django.conf import settings
urlpatterns += patterns('',
(r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
)
Try using the above given codes.
Above solution is perfectly ok. My problem was the improperly configured fixtures written in JSON and loaded into the database. I thought that in you pass articles directory as the upload_to kwarg, it'll be dynamically loaded. It's not. It is used only during saving the image and is ignored during loading the image from the database. Thus, if I had
"image":"slide.jpg"
I changed it to:
"image":"articles/slide.jpg"
And it worked. In fact, it worked all the time, but I miss a note on that in django official docs.
Did you try to use a upload method :
def upload_path(self, filename):
return 'media/articles/%s' % filename
class Article(models.Model):
...
image = models.ImageField(upload_to=upload_path, null=True, blank=True)
...
Related
I was getting tired of figuring out how to fix this problem. I checked a lot of different posts and answers but nothing helped me.
I have a form where I'm creating new advert. I have file input there for Image.
Form is valid and everything works fine, but my problem is that when I want to display my image from Advert model then it's not showing on website.. even the alt text.
My template code:
{% for advert in adverts %}
<img src="{{ advert.get_image }}" alt="test"/>
<div class="col-lg-4 col-md-6 col-sm-6">
<div class="mb-4 card">
<div id="second-advert" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="{{ advert.get_image }}" alt="test"/>
</div>
</div>
My urls.py:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('carapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My settings.py:
STATIC_URL = 'carsearch/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
My models.py:
class Advert(models.Model):
def get_image(self):
if self.featured_image and hasattr(self.featured_image, 'url'):
return self.featured_image.url
else:
return '/path/to/default/image'
owner = models.ForeignKey(Profile, null=True, blank=True, on_delete=models.SET_NULL)
title = models.CharField(max_length=200)
[...] <-- there's more code
featured_image = models.ImageField(null=True, blank=True, default='profiles/user.png', upload_to='adverts/')
[...] <-- there's more code
def __str__(self):
return self.title
My project structure:
enter image description here
And my website:
enter image description here
The image should appears above these two containers.. but it doesn't.
When I go to admin panel I can see added image in my model and I can click it and see it.
I also can see it in my database with python shell and with DB Browser for SQLite
But when I inspect the website then I can find my img tag but it is disabled(?)
enter image description here
enter image description here
And my views.py:
def adverts(request):
adverts = Advert.objects.all()
context = {'adverts': adverts, 'profile': profile}
return render(request, 'carapp/advertsView.html', context)
I tried many things from google and nothing works.. I also can say that I have a Profile form and Profile model. And there is also a photo which I can update and everything works there..
Actually I found a solution for this problem. Maybe it’s not what I expected but it helps.
The problem was in my featured_image field in models.py. I had to remove the attr upload_to=“images/adverts”
I am learning to write a Django app which will fetch all images from os.path.join(BASE_DIR, 'media_root', 'uploads') and show it on html page.
But its not working like so.
admin.py
from .models import Experience
# Register your models here.
admin.site.register(Experience)
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media_root')
MEDIA_URL = '/media/'
models.py
class Experience(models.Model):
id = models.AutoField(primary_key=True)
image = models.ImageField(upload_to='uploads/', default='newbalance.jpg', height_field=None, width_field=None)
studio_name = models.CharField(max_length=255)
designation = models.CharField(max_length=255)
duration = models.CharField(max_length=255)
description_short = models.TextField()
description_long = models.TextField()
keywords = models.CharField(max_length=255)
date = models.DateTimeField('DateAdded',
auto_now=True, auto_now_add=False)
class Meta:
db_table = "experience"
def __str__(self):
return self.studio_name + ' ' + self.duration
views.py
class ExperienceList(generic.ListView):
model = Experience
template_name = 'resumesection.html'
queryset = Experience.objects.all()
urls.py
urlpatterns = [
path('modelview/', views.ExperienceList.as_view(), name='experience_list'),
]
In error log,
2021-07-19 04:15:40,528: Not Found: /resume_site/modelview/uploads/atomic_arts.png
2021-07-19 04:15:41,239: Not Found: /resume_site/modelview/uploads/futureworks.jpg
I presume django should read image from 'MEDIA_ROOT/uploads' folder but it reads from '/resume_site/modelview/uploads/'. Which is not there.
I come close to the answer in this post Django admin view uploaded photo,
But cannot connect the dots between 'MEDIA_ROOT/uploads' and '/resume_site/modelview/uploads/'
How does viewing image, uploaded from admin, work in django. ?
EDIT: Part of resumesection.html in context
{% for exp in object_list %}
<h5>{{exp.studio_name}} | {{exp.duration}}</h5>
<img src="{{exp.image}}">
<p id="description_short_text">
{{exp.description_short}}
</p>
<p id="text" style="display:none;color:red">
{{exp.description_long}}
</p>
<h4 id='keywords_text' style="display:block;color:green">KEYWORDS</h4>
<p id='alt_text' style="display:block;color:green">{{exp.keywords}}</p>
{% endfor %}
urls.py in project
urlpatterns = [
path('admin/', admin.site.urls),
path('barefoot/', include('barefoot.urls')),
path('resume_site/', include('resume_site.urls')),
path('photo_gallery/', include('photo_gallery.urls')),
]
if settings.DEBUG: # added
import debug_toolbar
urlpatterns += [path('__debug__/', include(debug_toolbar.urls))]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if you are want to fetch a file from a db & want to place in src you have to provide .url in last
so use this
<img src="{{ exp.image.url }}">
instead of
<img src="{{exp.image}}">
read this for better understanding https://docs.djangoproject.com/en/3.2/topics/files/
and tell me if you still getting error
OK, so I have just done a rather extensive Django tutorial online and wanted to dive into my first project to see how I would go.
I started off alright and then hit a pretty big road block that I am trying to overcome with no luck, so if you guys could help I will be forever in your debt!
So the project itself is simply making a website for a few of my mates where we can login and view some stats on bets we have with each other.
What I have done so far:
I created two models in models.py with the following code:
from django.db import models
# Create your models here.
class Team(models.Model):
team_name = models.CharField(max_length=500, unique=True)
wins = models.PositiveIntegerField()
losses = models.PositiveIntegerField()
class Predictions(models.Model):
combined_teams = models.CharField(max_length=800)
player_name = models.CharField(max_length=200, primary_key=True)
predicted_wins = models.PositiveIntegerField()
def __str__ (self):
return self.player_name
I created a login screen, this is the first screen the user will come to (not relevant for the question)
I created a static folder with some css styling for a couple of the pages and made some minor changes to the settings files.
I then went on to setup my views.py file and a couple of urls.py files too, as follows:
###VIEWS.PY####
from django.shortcuts import render
from django.views.generic import TemplateView, ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Predictions, Team
class WelcomeView(LoginRequiredMixin,TemplateView):
template_name = 'merchbet/welcome.html'
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'merchbet/home.html'
class PredictionListView(LoginRequiredMixin, ListView):
model = Predictions
def get_queryset(self):
return Predictions.objects.order_by('-player_name')
class GalleryView(LoginRequiredMixin,TemplateView):
template_name = 'merchbet/gallery.html'
URLS.PY
from django.contrib import admin
from django.urls import path,include
from django.contrib.auth.urls import views
urlpatterns = [
path('', views.LoginView.as_view(), name='login'),
path('account/profile/', include('merchbet.urls')),
path('admin/', admin.site.urls),
]
URLS.PY### IN MY APP FOLDER
from django.urls import path
from . import views
app_name = 'merchbet'
urlpatterns = [
path('', views.WelcomeView.as_view(), name='welcome'),
path('home/', views.HomeView.as_view(), name='home'),
path('predictions/', views.PredictionListView.as_view(), name='prediction_list'),
path('gallery/', views.GalleryView.as_view(), name='gallery')
I then executed the following script, so that I could load up my friends "predictions" for our NBA bets this season with the following program:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','mysite.settings')
import django
django.setup()
from merchbet.models import Predictions, Team
predictions = ['Burger', 'Houston Rockets and Oklahoma City Thunder', 101,
'Buzz','Houston Rockets and Boston Celtics', 115, 'Kimon', 'Sacramento Kings and Atlanta Hawks', 44,
'Muller','Utah Jazz and Boston Celtics', 118, 'Barlow', 'Los Angeles Lakers and Milwaukee Bucks', 102,
'Larter','Golden State Warriors and Atlanta Hawks', 83, 'Hume', 'Los Andeles Lakers and Philadelphia 76ers',
104]
def add_predictions():
for index, entry in enumerate(predictions):
if index < len(predictions)-2:
if (type(predictions[index+2]) == type(1)):
player_name = predictions[index]
combined_teams = predictions[index+1]
predicted_wins = predictions[index+2]
preds = Predictions.objects.get_or_create(player_name=player_name,combined_teams=combined_teams,predicted_wins=predicted_wins)[0]
if __name__ == '__main__':
print("Populating the databases...Please Wait")
add_predictions()
print('Populating Complete')
The above worked fine and I can see in my Django Admin view of the site that there are 7 objects of the Predictions class all named after the "player_name" variable as it is the primary key:
So after all of this I am trying to simply use a for loop in an html document, that will help to print out the "player_name" and then I can show the "combined_teams" and "predicted_wins" but I just can not get it to work.
{% for prediction in prediction_list %}
<h1>{{ prediction.player_name }}</h1>
{% endfor %}
I have put a heap of effort into this post, so I am hoping some genius out there can lend a hand!
edit: I know the colour of the text is white, it is against a black background, so that isn't an issue :-)
Thanks!
You need to use object_list instead of prediction_list for merchbet/prediction_list.html, like this:
{% for prediction in object_list %}
<h1>{{ prediction.player_name }}</h1>
{% endfor %}
For more details, please check the documentation.
I have the following model containing an image field that I want to show up in my template show_item.html.
Models.py
class Item(models.Model):
def get_file(self, filename):
url = "%s/%s" % (settings.MEDIA_ROOT, filename)
return url
seller = models.ForeignKey(settings.AUTH_USER_MODEL)
pic1 = ImageField(blank=True, upload_to=get_file, max_length=500)
I know that MEDIA_ROOT and MEDIA_URL are properly configured.
The problem is that in my template, I try to access
<img src="{{ item.pic1 }}">
which fails to be found. Upon further investigation, this is because the path is showing up as the one in my file directory (e.g. /home/user/apps/media/filename) rather than the media_url (e.g. www.mysite.com/media/filename). I checked both locations and the image is in fact in both.
My question -- how do I access the url of the form www.mysite.com/media/filename in the template? I've tried {{ item.pic1.url }} as well, but it's still the path on my system.
Thanks!
If your image uploaded path can be accessed by the static path, just use the static url.
Or else I think you may write a url, pointing to a view to return the image response.
For example:
# in your urls.py
urlpatterns = patterns('',
url(r'^image/(?P<pk>\d+)/$', 'image_view', name='image_view'),
)
and then response the image content in the image view.
from django.core.servers.basehttp import FileWrapper
from django.http import StreamingHttpResponse
def image_view(request, pk):
item = Item.objects.get(pk=pk)
filename = item.pic1.url
wrapper = FileWrapper(open(filename, 'rb'))
response = StreamingHttpResponse(wrapper)
response['Content-Length'] = os.path.getsize(filename)
response['Content-Disposition'] = 'attachment; filename=image.jpg'
return response
I'm trying to use an example posted on the "github" the link is http://github.com/tstone/django-uploadify. And I'm having trouble getting work. can you help me? I followed step by step, but does not work.
Accessing the "URL" / upload /
the only thing is that returns "True"
part of settings.py
import os
PROJECT_ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(PROJECT_ROOT_PATH, 'media')
TEMPLATE_DIRS = ( os.path.join(PROJECT_ROOT_PATH, 'templates'))
urls.py
from django.conf.urls.defaults import *
from django.conf import settings
from teste.uploadify.views import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
url(r'upload/$', upload, name='uploadify_upload'),
)
views.py
from django.http import HttpResponse
import django.dispatch
upload_received = django.dispatch.Signal(providing_args=['data'])
def upload(request, *args, **kwargs):
if request.method == 'POST':
if request.FILES:
upload_received.send(sender='uploadify', data=request.FILES['Filedata'])
return HttpResponse('True')
models.py
from django.db import models
def upload_received_handler(sender, data, **kwargs):
if file:
new_media = Media.objects.create(
file = data,
new_upload = True,
)
new_media.save()
upload_received.connect(upload_received_handler, dispatch_uid='uploadify.media.upload_received')
class Media(models.Model):
file = models.FileField(upload_to='images/upload/', null=True, blank=True)
new_upload = models.BooleanField()
uploadify_tags.py
from django import template
from teste import settings
register = template.Library()
#register.inclusion_tag('uploadify/multi_file_upload.html', takes_context=True)
def multi_file_upload(context, upload_complete_url):
"""
* filesUploaded - The total number of files uploaded
* errors - The total number of errors while uploading
* allBytesLoaded - The total number of bytes uploaded
* speed - The average speed of all uploaded files
"""
return {
'upload_complete_url' : upload_complete_url,
'uploadify_path' : settings.UPLOADIFY_PATH, # checar essa linha
'upload_path' : settings.UPLOADIFY_UPLOAD_PATH,
}
template - uploadify/multi_file_upload.html
{% load uploadify_tags }{ multi_file_upload '/media/images/upload/' %}
<script type="text/javascript" src="{{ MEDIA_URL }}js/swfobject.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.uploadify.js"></script>
<div id="uploadify" class="multi-file-upload"><input id="fileInput" name="fileInput" type="file" /></div>
<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
$('#fileInput').uploadify({
'uploader' : '/media/swf/uploadify.swf',
'script' : '{% url uploadify_upload %}',
'cancelImg' : '/media/images/uploadify-remove.png/',
'auto' : true,
'folder' : '/media/images/upload/',
'multi' : true,
'onAllComplete' : allComplete
});
});
function allComplete(event, data) {
$('#uploadify').load('{{ upload_complete_url }}', {
'filesUploaded' : data.filesUploaded,
'errorCount' : data.errors,
'allBytesLoaded' : data.allBytesLoaded,
'speed' : data.speed
});
// raise custom event
$('#uploadify') .trigger('allUploadsComplete', data);
}
// ]]</script>
But that's exactly what you've told it to do - if you're not POSTing, then the /upload/ view will simply return True.
I would imagine you want to return an actual rendered template, presumably containing the {% multi_file_upload %} tag.
You may find the following site useful:
https://github.com/tstone/django-uploadify/wiki
line 1 on your template, your tags aren't properly closed/open
should be
{% load uploadify_tags %}{% multi_file_upload '/myphotos/my-photos/'%}
with that said, i am getting all sorts of errors my self... mainly with the csrf verification. i see that tstone is exempting csrf but it still thinks it should be there... and it isn't. so according to django's docs https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax i added the stuff to make it so csrf should be working. but now i get a 405 because it is trying to post to its self. i'll keep digging and hopefully find a solution.