E. Sutherland
E. Sutherland

Reputation: 111

How to Find Django ImageField URL

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

Answers (4)

almost a beginner
almost a beginner

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

Pran Kumar Sarkar
Pran Kumar Sarkar

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

E. Sutherland
E. Sutherland

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

Sergii Shcherbak
Sergii Shcherbak

Reputation: 977

In urls.py, try: static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Upvotes: 0

Related Questions