2012-07-11 11 views
6

Sono nuovo a Django e mi sto facendo strada attraverso "Il libro di Django" di Holovaty e Kaplan-Moss. Ho un progetto chiamato "mysite" che contiene due applicazioni chiamate "libri" e "contatti". Ognuno ha il proprio file view.py. Nel mio file urls.py Ho il seguente:Django - Importa viste da app separate

from books import views 
from contact import views 
... 
urlpatterns = patterns('', 
... 
(r'^search/$', views.search), 
(r'^contact/$', views.contact), 
... 

Quando eseguo il mio codice ottengo questo errore:

NameError a/ricerca/ ... valore Eccezione: oggetto 'modulo' ha senza attributo 'cerca'

Quello che credo stia accadendo è che dal momento che le viste dal contatto sono state importate per ultime, Django sta guardando la vista del contatto che non contiene la ricerca (la ricerca è nella vista dei libri).

Qual è il modo corretto di importare il file views.py da due applicazioni distinte all'interno di un file url di Django?

Grazie per il vostro aiuto!

risposta

15

responsabilità: Non un Django rispondere

Il problema è con queste due righe:

from books import views 
from contact import views 

La seconda importazione è shadowing la prima, in modo che quando si utilizza views tardi sei solo utilizzando il views da contact.

Una soluzione potrebbe essere quella di solo:

import books 
import contact 

urlpatterns = patterns('', 
... 
(r'^search/$', books.views.search), 
(r'^contact/$', contact.views.contact), 
... 

Non sono sicuro, ma penso anche che in realtà non c'è bisogno di importare nulla e può semplicemente utilizzare le stringhe nel vostro modello, qualcosa di simile: 'books.views.search'.


Un altro possiblity è quello di seguire Simon Visser suggerimento:

from books.views import search 
from contact.views import contact 
+0

Questo non ha funzionato, ma grazie per il suggerimento. – William

+1

@Robert: Ci sono stati un paio di errori di battitura (che ho risolto), a parte che è una soluzione funzionante. Non è necessario copiare e incollare le risposte nel codice, sarebbe meglio comprenderle e trovare il proprio modo di risolvere il problema. Sei anche libero di accettare [http://meta.stackexchange.com/a/5235/177799] la risposta che ti ha aiutato di più. –

+0

Anche Rik, il tuo secondo suggerimento via Simon Visser, ha funzionato. Grazie. – William

4
from books import views 
from contact import views 

si sovrascrive il nome views. Devi importarli come nomi diversi o come nomi assoluti.

import books.views 
import contact.views 

... o ...

from books import views as books_views 
from contact import views as contact_views 

quindi utilizzare il nome corretto durante la definizione degli URL. (books.views.search o books_views.search a seconda del metodo scelto)

+0

Questo _did_ funziona. Grazie mille! – William

+1

È più comune fare 'da books.views import search' e' da contact.views import contact'. Dopotutto, vuoi importare le funzioni di visualizzazione, non i moduli di visualizzazione. –

+0

@RobertF. se ha funzionato per te, assicurati di accettare la risposta facendo clic sul segno di spunta. –

2

Il URLconfs documentation dà un esempio della stessa situazione

È possibile saltare le importazioni e separare gli URL da app come tale:

urlpatterns = patterns('books.views', 
    (r'^/book/search/$', 'search'), #calls books.views.search 
) 

urlpatterns += patterns('contact.views', #make note of the '+=' 
    (r'^/contact/search/$', 'search'), #calls contact.views.search 
) 
+0

Molto interessante.Grazie per averlo indicato. – William

+0

Grazie per questo, 4 anni dopo: 3 – Lucas

+0

Solo per segnalare che django.conf.urls.patterns() è stato rimosso in Django 1.10. https://docs.djangoproject.com/en/1.10/releases/1.10/#features-removed-in-1-10 – azalea

1

Il La ragione per cui sto rispondendo a questa domanda è perché gli è stata data risposta anni fa e quelle risposte non sono più corrette o utili per le nuove versioni di Django, o c'è una pratica migliore che dovresti conoscere.

Quindi, se nel tuo progetto Django hai più di un'app, dovresti utilizzare un nuovo file urls.py per ognuna delle tue app. Significa che se avvii una nuova app devi creare manualmente un nuovo file chiamato urls.py nella sottocartella della tua nuova app. Molti principianti non capiscono perché questo è buono, ma questa è una buona pratica se pianifichi di creare più app in un progetto Django.

Quando si avvia un progetto, il file urls.py viene creato automaticamente nella cartella del progetto, ma se si crea/avvia una nuova app in Django, allora è una buona pratica se si crea un urls.py separato per quello app nella propria cartella. (E in questo modo non avrai mai il problema "importare le diverse visualizzazioni dell'app in urls.py" in primo luogo).

Dopo aver creato il file urls.py per la vostra applicazione, allora dovete includere del quel file urls.py dell'applicazione nel file di urls.py del progetto nel modo seguente:

Vediamo un esempio quando crei una nuova app chiamata "my_new_app". Questo è il modo di file urls.py principale del progetto dovrebbe essere simile:

from django.conf.urls import url, include 
from django.contrib import admin 

urlpatterns = [ 
    url(r'^admin/', admin.site.urls), 
    url(r'^my_new_app/', include('my_new_app.urls')), 
] 

Nel file di urls.py del progetto è necessario importare il metodo di 'comprendere', allora si può includere il file urls.py my_new_app in il file urls.py principale del tuo progetto. Nella tua cartella my_new_app devi creare manualmente un file urls.py come ho detto sopra. Quindi devi usare quel file per tutti i tuoi urlpatterns di my_new_app. Quindi, ovviamente, in questo modo verrà automaticamente incluso nel file urls.py principale del progetto.

Quindi questo è allora come un tuo file urls.py my_new_app dovrebbe essere simile:

from django.conf.urls import url 
from my_new_app import views 

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

Supponendo che anche è stata creata una prima vista chiamata ‘indice’ nel ‘file di my_new_app/views.py.

my_new_app/aspetto del file views.py come questo:

from django.shortcuts import render 
from django.http import HttpResponse 

def index(request): 
    return HttpResponse("Hello World!") 

E si può controllare la my_new_app nel tuo browser su:

http://localhost:8000/my_new_app 

(naturalmente si può dare alcuna url al tuo my_new_app nel file urls.py del tuo progetto.)

Ora puoi creare un'altra app, nel tuo progetto Django, chiamata my_second_app e dovresti ripetere i passaggi precedenti anche per quell'app. In questo modo non avrai problemi a importare viste da diverse app nei file urls.py. Questa sarebbe una "buona pratica" soluzione per questo problema nel 2017 in Django 1.11.