Fichier non reconnu dans un module

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

Je travaille avec Django, et je ne parviens pas à importer un fichier d'un module, alors que ceux voisins sont accessibles :

1
2
3
4
5
6
7
$ ls projects/
admin.py  apps.py  forms.py  __init__.py  migrations  models.py  __pycache__  static  templates  tests.py  urls.py  views
$ ls projects/views/
account.py  correspondent.py  __init__.py  manager.py  __pycache__
$ ./manage.py runserver
[...]
AttributeError: module 'projects.views' has no attribute 'account'

L'erreur provient du fichier projects/urls.py :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.conf.urls import url

from . import views

app_name = 'projects'
urlpatterns = [
    url(r'^$', views.account.index, name='index'),
    url(r'^(?P<pk>[0-9]+)/(?P<slug>[-_\w]*)$', views.correspondent.edit_project, name='edit'),
    url(r'^previsualiser/projet/(?P<pk>[0-9]+)/(?P<slug>[-_\w]*)$', views.correspondent.preview_project, name='preview'),
    url(r'^editer/progression/(?P<project_pk>[0-9]+)$', views.correspondent.set_progression, name='set_progression'),
    url(r'^supprimer/section/(?P<pk>[0-9]+)$', views.correspondent.delete_section, name='delete_section'),
    url(r'^ajouter/image/(?P<project_pk>[0-9]+)$', views.correspondent.add_image, name='add_image'),
    url(r'^ajouter/video/(?P<project_pk>[0-9]+)$', views.correspondent.add_video, name='add_video'),
    url(r'^ajouter/section/(?P<project_pk>[0-9]+)$', views.correspondent.add_section, name='add_section'),
    # Manager
    url(r'^valider$', views.manager.validate, name='validate'),
    url(r'^valider/projet/(?P<pk>[0-9]+)$', views.manager.validate_project, name='validate_project'),
    url(r'^valider/progressions$', views.manager.validate_progressions, name='validate_progressions'),
    url(r'^valider/images$', views.manager.validate_images, name='validate_images'),
    url(r'^valider/videos$', views.manager.validate_videos, name='validate_videos'),
    url(r'^creer$', views.manager.create, name='create'),
    url(r'^archiver/(?P<pk>[0-9]+)$', views.manager.archive, name='archive'),
    # Accounts
    url(r'^connexion$', views.account.login, name='login'),
    url(r'^deconnexion$', views.account.logout, name='logout'),
]

Quand je commente la ligne 7, c'est la 24 qui fait gueuler.

Merci.

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

Il y a quoi dans ton views/__init__.py ? Tu es sur Python 2 ou 3 ?

edit: Sinon ça peut être dut à une importation circulaire mais faudrait voir ce qu'il y a avant dans ton message d'erreur

Édité par Kje

+1 -0
Auteur du sujet

Python 3. Mon __init__.py contient :

1
2
from . import correspondent
from . import manager

Et je me fais effectivement avoir à chaque fois : les fichiers d'un module ne sont pas accessibles automatiquement en Python 3. Merci. :)

+0 -0
Staff

(petite remarque : évite les from . import foo et préfère les from bar import foo ;) )

"I think that it’s extraordinarily important that we in computer science keep fun in computing." – Alan J. Perlis

+0 -1
Staff

C'est une bonne pratique d'utiliser les chemins complets. (bar = projet.app.views)

"I think that it’s extraordinarily important that we in computer science keep fun in computing." – Alan J. Perlis

+0 -0

Cette réponse a aidé l'auteur du sujet

C'est une clause de la PEP8 qui recommande d'utiliser les imports absolus : https://www.python.org/dev/peps/pep-0008/#imports

Mais il faut noter qu'elle autorise les imports relatifs explicites dans le cas de packages complexes, ce qui semble être le cas dans une application Django.

Staff

Mais il faut noter qu'elle autorise les imports relatifs explicites dans le cas de packages complexes, ce qui semble être le cas dans une application Django.

entwanne

Pas d'accord sur ce point. Django utilise une structure extrêmement bien agencée, à proscrire donc.

"I think that it’s extraordinarily important that we in computer science keep fun in computing." – Alan J. Perlis

+0 -0

Un gros projet Django bien découpé comprend souvent de nombreux packages inclus les uns dans les autres (vues dans applications dans projet). C'est bien agencé, oui, mais ça fait des noms de modules à rallonge. Et il semble plus clair, quand on voit un from .view dans un fichier d'URLs, qu'on se réfère aux vues de l'application courante.

À conseiller, donc.

Staff

Désolé mais je ne peux pas te laisser dire ça. Regarde des gros projets en Django, tu n'as jamais ça.

"I think that it’s extraordinarily important that we in computer science keep fun in computing." – Alan J. Perlis

+0 -0

Une grande majorité des projets Django ont été écrits sous Python 2 (le support du Python 3 par Django étant relativement récent), où les imports relatifs explicites n'existaient que via une utilisation de __future__. Il paraît donc normal que ce soit une pratique assez peu répandue.

J'ai toutefois regardé quelques projets Django au hasard sur Github (les sélectionnant par rapport à leur nombre de stars), et je tombe souvent sur des imports relatifs implicites qui sont pour le coup vraiment à proscrire. Par exemple :

Édité par entwanne

Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte