2012-07-11 9 views
6

Jestem nowy w Django i pracuję nad książką "The Django Book" Holovatiego i Kaplana-Mossa. Mam projekt o nazwie "mysite", który zawiera dwie aplikacje o nazwie "książki" i "kontakt". Każdy ma swój własny plik view.py. W moim urls.py pliku mam następujące:Django - Importuj widoki z oddzielnych aplikacji

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

Kiedy uruchomić mój kod otrzymuję ten błąd:

NameError w/search/ ... wartości wyjątek: „moduł” obiekt ma brak atrybutu "szukaj"

W moim przekonaniu Django patrzy na widok kontaktu, który nie zawiera wyszukiwania (wyszukiwanie jest w widoku książek).

Jaki jest właściwy sposób importowania pliku views.py z dwóch różnych aplikacji w pliku URL Django?

Dzięki za pomoc!

Odpowiedz

15

Zastrzeżenie: Nie Django odpowiedzieć

Problem jest z tych dwóch linii:

from books import views 
from contact import views 

Drugi importu shadowing pierwszy, więc kiedy używają views później jesteś tylko przy użyciu views z contact.

Jednym z rozwiązań może być po prostu:

import books 
import contact 

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

Nie jestem pewien, ale myślę też, że w rzeczywistości nie trzeba importować niczego i można po prostu używać strun w swojej strukturze, coś jak: 'books.views.search'.


Kolejna możliwo jest przestrzeganie Simon Visser sugestia:

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

To nie działało, ale dzięki za sugestię. – William

+1

@Robert: Było kilka literówek (które naprawiłem), poza tym jest to działające rozwiązanie. Nie musisz kopiować i wklejać naszych odpowiedzi do kodu, lepiej byłoby je zrozumieć i znaleźć własny sposób rozwiązania problemu. Możesz również [zaakceptować] (http://meta.stackexchange.com/a/5235/177799) odpowiedź, która pomogła ci najbardziej. –

+0

Rik, twoja druga sugestia za pośrednictwem Simona Vissera również zadziałała. Dzięki. – William

4
from books import views 
from contact import views 

została zastąpiona nazwę views. Musisz zaimportować je jako różne nazwy lub jako nazwy bezwzględne.

import books.views 
import contact.views 

... albo ...

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

Następnie używać poprawnej nazwy podczas definiowania adresów URL. (books.views.search lub books_views.search w zależności od wybranej metody)

+0

To _did_ pracy. Dziękuję bardzo! – William

+1

Częściej jednak robi się "z przeglądarki importu books.views" i "z kontaktu contact.views import". W końcu chcesz zaimportować funkcje widoku, a nie moduły widoku. –

+0

@RobertF. jeśli to zadziałało dla ciebie, pamiętaj, aby zaakceptować odpowiedź, klikając znacznik wyboru. –

2

URLconfs documentation podaje przykład takiej samej sytuacji

można pominąć importu i oddzielne adresy URL przez aplikację jako takie:

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

Bardzo interesujące.Dziękuję za wskazanie tego. – William

+0

Dziękuję za to, 4 lata później: 3 – Lucas

+0

Po prostu wskazuję, że django.conf.urls.patterns() został usunięty w Django 1.10. https://docs.djangoproject.com/en/1.10/releases/1.10/#features-removed-in-1-10 – azalea

1

powodem, dla którego odpowiadam na to pytanie, jest to, że odpowiedź została udzielona lata temu, a odpowiedzi te nie są poprawne lub przydatne dla nowszych wersji Django, lub jest lepsza praktyka, o której powinieneś wiedzieć.

Tak więc, jeśli masz więcej niż jedną aplikację w swoim projekcie Django, powinieneś użyć nowego pliku urls.py dla każdej aplikacji. Oznacza to, że jeśli uruchomisz nową aplikację, musisz ręcznie utworzyć nowy plik o nazwie urls.py w podfolderze nowej aplikacji. Wielu początkujących nie rozumie, dlaczego jest to dobre, ale jest to dobra praktyka, jeśli planujesz tworzyć więcej aplikacji w jednym projekcie Django.

Po uruchomieniu projektu plik urls.py zostanie automatycznie utworzony w folderze projektu, ale jeśli utworzysz/uruchomisz nową aplikację w Django, dobrym pomysłem jest utworzenie osobnego pliku urls.py dla tego pliku. aplikacja w swoim własnym folderze. (I w ten sposób nigdy nie będziesz mieć problemu z "importowaniem różnych aplikacji do urls.py").

Po utworzeniu pliku urls.py dla swojej aplikacji, a następnie trzeba obejmują że plik urls.py app w pliku urls.py Twojego projektu w następujący sposób:

Spójrzmy na przykład podczas tworzysz nową aplikację o nazwie "my_new_app". ten sposób główny plik urls.py Twój projekt powinien wyglądać następująco:

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')), 
] 

W urls.py złożyć projektu trzeba importować metodę „obejmować”, a następnie można dołączyć plik urls.py my_new_app w główny plik urls.py Twojego projektu. W folderze my_new_app musisz ręcznie utworzyć plik urls.py, jak wskazałem powyżej. Następnie musisz użyć tego pliku dla wszystkich twoich urlwzorów twojej my_new_app. Wtedy oczywiście zostanie automatycznie włączony do głównego pliku urls.py twojego projektu.

Więc to jest to jak Twój my_new_app własny plik urls.py powinna wyglądać następująco:

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

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

Zakładając, że stworzył także pierwszy widok o nazwie „Indeks” w „my_new_app pliku/views.py.

my_new_app/views.py plik wyglądać następująco:

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

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

I można sprawdzić my_new_app w przeglądarce pod adresem:

http://localhost:8000/my_new_app 

(Oczywiście można podać dowolny adres URL do my_new_app w pliku urls.py twojego projektu.)

Teraz możesz utworzyć kolejną aplikację w swoim projekcie Django o nazwie my_second_app i powinieneś powtórzyć powyższe kroki dla tej aplikacji. W ten sposób nie będziesz miał problemu z importowaniem widoków z różnych aplikacji do plików urls.py. Byłoby to bardzo podstawowe "dobre rozwiązanie" dla tego problemu w 2017 roku w Django 1.11.