Reputation: 111
I'm trying to accomplish something I believed would be simple: upload an image (via admin), then use the complete URL in a template to display the image.
The problem is I can only print the relative URL: /pics/filename.jpg. I believe the sequence is settings.py (MEDIA_ROOT, MEDIA_URL), urls.py, views.py and then mytemplate.html.I hope someone can find what's missing.
Settings:
STATIC_URL = '/static/'
MEDIA_ROOT = '/Users/ed/code/projects/djcms/pics/'
MEDIA_URL = '/pics/'
Urls.py:
from django.conf import settings
from django.conf.urls.static import url, static
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^news/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
] + static(r'^$/pics/', document_root = settings.MEDIA_URL)
Views.py
def detail(request, pk):
story = Article.objects.get(pk=pk)
my_pic = Photo.objects.get(pk=pk)
print(story.image.url)
print(my_pic)
print(story.body)
print(request)
context = {'story': story}
return render(request, 'articles/detail.html', context)
The Error with story.image.url:
AttributeError: 'Photo' object has no attribute 'url'
When I remove the .url, I get this partial URL:
pics/intro-bg.jpg
What am I missing? Thanks.
Upvotes: 4
Views: 20943
Reputation: 1632
This setup is working for me, maybe it will help you. It is for latest version of Django. Many answers in OS are for older Django versions.
URLS:
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
#url
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Settings:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Template:
<img src="{{ foo.image.url }}"><br>
Model:
image = models.ImageField(upload_to = 'img/', default = 'img/None/no-img.jpg')
My foo model has an imagefield, when it is stored, I can retrieve the full url through item.image.url
based on the above setup.
Upvotes: 3
Reputation: 1003
The Request object in Django has a method,
build_absolute_uri()
Using this method you can get absolute url of the image field.
So to get the absolute url, you can use two methods
First method: Getting absolute url in view while doing GET request.
from settings import MEDIA_URL
class ClassName(APIView):
def get(self, *args, **kwargs):
model = models.ModelName.objects.get(name='pran')
absolute_url = self.request.build_absolute_uri('/').strip("/") + MEDIA_URL + str(model.image_field_name)
return Response({'url': absolute_url}, 200)
Method 2: If you are doing POST request and you are using serializer then pass request as context object to it.
ser = serializers.MySerializerName(data=request.data}, context={'request': request})
Upvotes: 0
Reputation: 111
The URLS seem to be causing the problem.
from django.conf import settings
from django.conf.urls.static import url, static
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^news/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The logic behind those URL patterns displays my homepage and individual news articles. Each news article has a url of /news/, followed by the article number, i.e. /news/1.
Each article uses my Photo model via a ForeignKey in the Article model. This allows a photo to be tied to a specific article.
However, in my template, the URL is a jumble of news and images:
http://localhost:8000/news/2/img/phones.png.
The news URL correctly finds the news item but not the image associated with the news item. The correct result would display the individual article along with its associated image. Do I need another URL?
Upvotes: 0
Reputation: 977
In urls.py, try: static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Upvotes: 0