Django pobiera adresy URL plików statycznych w widoku

133

Używam reportlab pdfgen do tworzenia plików PDF. W pliku PDF znajduje się obraz utworzony przez drawImage. W tym celu potrzebuję adresu URL do obrazu lub ścieżki do obrazu w widoku. Udało mi się zbudować adres URL, ale jak uzyskać lokalną ścieżkę do obrazu?

Jak uzyskać adres URL:

prefix = 'https://' if request.is_secure() else 'http://'
image_url = prefix + request.get_host() + STATIC_URL + "images/logo_80.png"
olofom
źródło

Odpowiedzi:

287

Ponieważ jest to najlepszy wynik w Google, pomyślałem, że dodam inny sposób, aby to zrobić. Osobiście wolę ten, ponieważ pozostawia implementację frameworkowi Django.

# Original answer said:
# from django.templatetags.static import static
# Improved answer (thanks @Kenial, see below)
from django.contrib.staticfiles.templatetags.staticfiles import static

url = static('x.jpg')
# url now contains '/static/x.jpg', assuming a static path of '/static/'
dyve
źródło
2
Czy wiesz, czy istnieje czysty sposób dodania nazwy hosta do statycznego adresu URL (jeśli nie ma go w STATIC_URL)? Muszę dodać obrazy lub inne zasoby w wiadomościach e-mail, w przypadku których użytkownik nie będzie mógł znaleźć zasobów ze względnymi adresami URL.
gepatino
3
To nie działa dla mnie podczas uruchamiania w trybie Debug (nie próbowałem jeszcze z DEBUG = False). Po prostu otrzymuję ścieżkę przekazaną do metody statycznej. Korzystanie z Django 1.6. jakieś pomysły?
Shawn
Myślę, że kod używający django.contrib.staticfiles.templatetags.staticfiles powinien być preferowany, biorąc pod uwagę, że jest kompatybilny z magazynami django i podobnymi.
jdcaballerov
@gepatino Możesz skierować wynik request.build_absolute_urizgodnie z opisem tutaj: stackoverflow.com/questions/2345708/ ...
dyve
17
W Django 2.0 to pokaże informację o wycofaniu. Użyj from django.templatetags.static import staticzamiast tego.
Flimm
86

odpowiedź dyve jest dobra, jednak jeśli używasz "pamięci podręcznej" w swoim projekcie django i końcowe ścieżki url plików statycznych powinny zostać "zaszyfrowane" (np. style.aaddd9d8d8d7.css z style.css ), wtedy nie można uzyskać dokładnego adresu URL z django.templatetags.static.static(). Zamiast tego musisz użyć tagu szablonu z, django.contrib.staticfilesaby uzyskać zaszyfrowany adres URL.

Dodatkowo, w przypadku korzystania z serwera deweloperskiego, ta metoda tagu szablonu zwraca niehaszowany adres URL, więc możesz użyć tego kodu niezależnie od hosta, na którym jest programowany czy produkcyjny! :)

from django.contrib.staticfiles.templatetags.staticfiles import static

# 'css/style.css' file should exist in static path. otherwise, error will occur 
url = static('css/style.css')
Kenial
źródło
1
Dzięki za to ... zajęło mi trochę czasu,
zanim zrozumiałem
4
Ta odpowiedź wciąż jest trafiana i jest aktywnie używana, więc poprawiłem moją zaakceptowaną odpowiedź dzięki kredytom dla @Kenial. Jest to nadal preferowane rozwiązanie tego problemu.
dyve
12

oto inny sposób! (testowane na Django 1.6)

from django.contrib.staticfiles.storage import staticfiles_storage
staticfiles_storage.url(path)
David Lam
źródło
Dobre rozwiązanie, ponieważ zwróci zaszyfrowany adres URL, jeśli DEBUG jest ustawiony na Fałsz. Opcjonalnie wymuś zaszyfrowany adres URL w następujący sposób: staticfiles_storage.url(path, force=True)
Marc Gibbons
7

Użyj domyślnego statictagu:

from django.templatetags.static import static
static('favicon.ico')

Jest inny tag django.contrib.staticfiles.templatetags.staticfiles(jak w zaakceptowanej odpowiedzi), ale jest on przestarzały w Django 2.0+.

Max Malysh
źródło
6

Od Django 3.0 powinieneś używać from django.templatetags.static import static:

from django.templatetags.static import static

...

img_url = static('images/logo_80.png')
devaerial
źródło
5

Odpowiedź @ dyve nie działa dla mnie na serwerze deweloperskim. Zamiast tego rozwiązałem to za pomocą find. Oto funkcja:

from django.conf import settings
from django.contrib.staticfiles.finders import find
from django.templatetags.static import static

def get_static(path):
    if settings.DEBUG:
        return find(path)
    else:
        return static(path)
Jahongir Rahmonov
źródło
1

Jeśli chcesz uzyskać bezwzględny adres URL (w tym protokół, host i port), możesz użyć request.build_absolute_urifunkcji pokazanej poniżej:

from django.contrib.staticfiles.storage import staticfiles_storage
self.request.build_absolute_uri(staticfiles_storage.url('my-static-image.png'))
# 'http://localhost:8000/static/my-static-image.png'
Mesut Tasci
źródło