2012-07-11 8 views
6

Soy nuevo en Django y estoy trabajando en "The Django Book" de Holovaty y Kaplan-Moss. Tengo un proyecto llamado "mysite" que contiene dos aplicaciones llamadas "libros" y "contacto". Cada uno tiene su propio archivo view.py. En mi archivo urls.py Tengo el siguiente:Django: Importe vistas desde aplicaciones separadas

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

Cuando ejecuto mi código me sale este error:

NameError en/de búsqueda ... valor/Excepción: Objeto de 'módulo' tiene no atributo 'buscar'

Lo que creo que está sucediendo es que dado que las vistas de contacto se importaron al último, Django está mirando la vista de contacto que no contiene búsqueda (la búsqueda está en la vista de libros).

¿Cuál es la forma correcta de importar el archivo views.py de dos aplicaciones distintas dentro de un archivo de URL de Django?

Gracias por su ayuda!

Respuesta

15

responsabilidad: No es un Django responder

El problema es con estas dos líneas:

from books import views 
from contact import views 

La segunda importación se cubrían el primero de ellos, por lo que cuando se utiliza views tarde sólo estás usando el views de contact.

Una solución podría ser simplemente:

import books 
import contact 

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

No estoy seguro, pero también creo que en realidad no necesita importar nada y sólo pueden utilizar cadenas en su patrón, algo así como: 'books.views.search'.


Otra posibilidad es seguir Simon Visser sugerencia:

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

Esto no funcionó, pero gracias por la sugerencia. – William

+1

@Robert: Hubo un par de errores tipográficos (que arreglé), aparte de eso es una solución de trabajo. No tiene que copiar y pegar nuestras respuestas en su código, sería mejor comprenderlas y encontrar su propia manera de solucionar su problema. También puede [aceptar] (http://meta.stackexchange.com/a/5235/177799) la respuesta que más le ayudó. –

+0

Rik, tu segunda sugerencia a través de Simon Visser también funcionó. Gracias. – William

4
from books import views 
from contact import views 

va a sobrescribir el nombre views. Debe importarlos como nombres diferentes o como nombres absolutos.

import books.views 
import contact.views 

... o ...

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

luego usar el nombre correcto al definir sus URL. (books.views.search o books_views.search dependiendo del método que elija)

+0

Este _did_ trabajo. ¡Muchas gracias! – William

+1

Es más común hacer 'from books.views import search' y' from contact.views import contact'. Después de todo, desea importar las funciones de vista, no los módulos de vista. –

+0

@RobertF. si le funcionó, asegúrese de aceptar la respuesta haciendo clic en la marca de verificación. –

2

El URLconfs documentation da un ejemplo de la misma situación

Puede saltar las importaciones y separar las direcciones URL de la aplicación como tal:

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

Muy interesante.Gracias por señalar eso. – William

+0

Gracias por esto, 4 años después: 3 – Lucas

+0

Solo para señalar que django.conf.urls.patterns() se elimina en Django 1.10. https://docs.djangoproject.com/en/1.10/releases/1.10/#features-removed-in-1-10 – azalea

1

El La razón por la que respondo esta pregunta es porque fue respondida hace años y esas respuestas ya no son correctas o útiles para las versiones más nuevas de Django, o hay una mejor práctica que debe conocer.

Por lo tanto, si tiene más de una aplicación en su proyecto Django, debe usar un nuevo archivo urls.py para cada una de sus aplicaciones. Significa que si inicia una nueva aplicación, debe crear manualmente un nuevo archivo llamado urls.py en la subcarpeta de su nueva aplicación. Muchos principiantes primero no entienden por qué esto es bueno, pero esta es una buena práctica si planea crear más aplicaciones en un proyecto de Django.

Cuando inicia un proyecto, el archivo urls.py se crea automáticamente en su carpeta de proyecto, pero si crea/inicia una nueva aplicación en Django, entonces es una buena práctica si crea un urls.py separado para ese aplicación en su propia carpeta. (Y de esa manera nunca tendrás el problema de "importar diferentes vistas de aplicaciones en urls.py" en primer lugar).

Después de crear el archivo urls.py para su aplicación, entonces usted tiene que incluyen ese archivo urls.py de aplicación en el archivo urls.py de su proyecto de la siguiente manera:

Veamos un ejemplo, cuando creas una nueva aplicación llamada 'my_new_app'. Esta es la forma en archivo urls.py principal de su proyecto debe verse como:

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

En urls.py archivo de su proyecto que tiene que importar el método de 'incluir', entonces usted puede incluir su archivo urls.py my_new_app en el archivo urls.py principal de su proyecto. En su carpeta my_new_app, debe crear manualmente un archivo urls.py como mencioné anteriormente. Luego debes usar ese archivo para todos tus patrones de tu my_new_app. Entonces, por supuesto, de esta manera se incluirá automáticamente en el archivo urls.py principal de su proyecto.

Así que este es entonces cómo su propio archivo urls.py my_new_app debe verse como:

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

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

Suponiendo que también se creó una primera vista se llama ‘índice’ en su ‘archivo my_new_app/views.py.

my_new_app/mirada archivo views.py así:

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

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

Y se puede comprobar su my_new_app en su navegador en:

http://localhost:8000/my_new_app 

(por supuesto se puede dar a cualquier URL a su my_new_app en el archivo urls.py de su proyecto)

Ahora puede crear otra aplicación en su proyecto Django, llamada my_second_app, y debe repetir los pasos anteriores para esa aplicación también. De esta forma, no tendrás problemas para importar vistas de diferentes aplicaciones a archivos urls.py. Esta sería una "solución de buenas prácticas" muy básica para este problema en 2017 en Django 1.11.

Cuestiones relacionadas