Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Django et upload de fichier

+4 votes

Je n'arrive pas à intégrer un fichier dans ma page html ( je suis avec la version 1.8 dev de django ):
Mon model :

def content_file_name(instance, filename):
    return '/'.join(['content', instance.slug, filename])

class Even(models.Model):
    ...
    docfile = models.FileField(upload_to=content_file_name)

Mon fichier html :

<img src="{{question.docfile.url}}">

Dans le setting je déclare le media :

MEDIA_ROOT = '/srv/www/last/test/media/'
MEDIA_URL = '/media/'

L'image s'upload bien ou je veux mais je n'arrive pas à l'afficher , le code source de la page générée me donne :

<img src="/media/content/test/archives.jpg" />

J'ai un problème de variable, de chemin mais je ne trouve pas, ou peut être un bug de la version dev.
Question subsidiaire : dans la doc j'ai vu des uploads avec filesystemstorage, est-ce une nouvelle manière de faire ?

demandé 9-Jan-2015 par mortim3r
edité 9-Jan-2015 par Sam

Dans les logs du serveur http on a quel code retour? 404 200 ?

Perso, je ne saisis pas trop le contexte, peux tu donner en entier, le model, la vue, et l'url que tu utilises?
Sinon, en mode Debug=True, et uniquement dans ce mode, modifier le fichier urls et ajouter ceci.

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
    ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Lancer le serveur et aller a l'url MEDIA_URL pour voir si tout baigne.

Je met précisément le contenu :

Mon modéle :

from django.db import models

def content_file_name(instance, filename):
    return '/'.join(['agenda/media', instance.slug, filename])

fs = FileSystemStorage(base_url='MEDIA_URL',location='agenda/')

class Orga(models.Model):
    name = models.CharField(max_length=100)
    ville = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Even(models.Model):
    titre = models.CharField(max_length=100)
    slug = models.SlugField(null=False, blank=False, unique=True, default='')
    pub_date = models.DateTimeField('date published')
    resume = models.TextField()
    orga = models.ForeignKey(Orga)
    docfile = models.FileField(upload_to=content_file_name)

    def __str__(self):              # __unicode__ on Python 
        return self.titre

Mon urls.py du projet :

from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.conf.urls import *  # NOQA
from django.contrib.staticfiles.urls import staticfiles_urlpatterns


urlpatterns = [
    # Examples:
    # url(r'^$', 'essais.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^agenda/', include('agenda.urls', namespace="agenda")),
]

if settings.DEBUG:
    urlpatterns = patterns('',
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve',  # NOQA
            {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
        ) + staticfiles_urlpatterns() + urlpatterns  # NOQA

Mon urls.py de l'app :

from django.conf.urls import url

from agenda import views

urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
]

Mon admin.py:

from django.contrib import admin
from agenda.models import Orga, Even

class EvenAdmin(admin.ModelAdmin) :
    search_fields= ["titre"]
    prepopulated_fields = {"slug": ("titre",)}

admin.site.register(Orga)
admin.site.register(Even, EvenAdmin)

le settings :
>

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    ('static'),
)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

Avec le debug dans l'urls.py, les images s'affichent.
Sans le debug, j'ai le droit un un beau 404, dans les logs :

[12/Jan/2015 08:05:19]"GET /media/agenda/media/css-et-xhtml/archives.jpg HTTP/1.1" 200 10863
[12/Jan/2015 08:04:52]"GET /media/agenda/media/css-et-xhtml/archives.jpg HTTP/1.1" 404 2147

Pour du test c'est pas grave, mais je viens bêtement de penser qu'avec ngninx le comportement sera différent pour servir ces fichiers images. Est-ce le comportement normal du runserver ?

Oui, c'est le comportement normal du runserver. En mode debug, il facilite la vie du developpeur en servant les contenus statiques, en prod, tes images doivent être servies par un logiciel optimisé pour ça : nginx, apache, lighttpd. Django peut servir ces images, mais ça va mettre ton process WSGI à genoux.

Merci pour ces réponses et précisions aussi rapides. Je mériterais un tampon gros boulet.
Pour valider en meilleur réponse, à quel niveau je le fais là, vu qu'il n'y en a pas vraiment, ce ne sont que des commentaires ?

Dis nous l'info qui t'a donné le déclic, et j'en fais une réponse que tu pourras accepter.

Pas de boulet à mes yeux, l'ignorance n'est pas un manque d'intelligence, et la question été suivie, commentaire par commentaire. C'est exactement le but du site.

A noter cet article sur le blog sur les fichiers statiques et django :

http://sametmax.com/comment-servir-les-fichiers-statiques-avec-django-en-dev-et-en-prod/

D'une manière générale, on a quelques tutos utiles sur django ici :

http://sametmax.com/cours-et-tutos/

Le mode debug donné par Nsukami_, même si je n'ai pas mis à l'identique, m'a permit de voir que les media root / media url étaient bons.
Avec la remarque de Foxmask sur les logs, j'ai bien vu que cétait le mode debug et le serveur de dev qui fournissaient les images, plus un petit problème avec des images sur un serveur avec apache. Toutes les réponses ont contribué au résultat, merci.

Merci Sametmax pour tous ces tutos et votre boulot .
Ps : sous iceweasel, j'ai de grosses difficultés à remplir le champs de commentaire, problèmes de script.

1 Réponse

+3 votes
 
Meilleure réponse

Ceci n'est pas une reponse directe à ta requete. Mais ça pourra peut être t'aider à mieux voir ce qui se passe. En mode Debug=True, et uniquement dans ce mode, modifier le fichier urls et ajouter ceci.

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = patterns('',
    # ... the rest of your URLconf goes here ...
    ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Lancer le serveur et aller à l'url MEDIA_URL pour voir si tout baigne.

répondu 13-Jan-2015 par Nsukami_ (1,998 points)
edité 13-Jan-2015 par foxmask
...