2010-01-08 6 views
8

Estoy escribiendo aplicaciones reutilizables. Y quiero implementarlo varias veces.¿Cómo obtener current_app para usar con el reverso en la aplicación Django reutilizable y de múltiples aplicaciones?

Aquí es urls.py:

urlpatterns = patterns('', 
(r'^carphotos/', include('webui.photos.urls', app_name='car-photos')), 
(r'^userphotos/', include('webui.photos.urls', app_name='profile-photos')),) 

y fotos/urls.py:

urlpatterns = patterns('webui.photos.views', 
url(r'^$', album_list, name="album-list") 
url(r'^newalbum/$', album_page, {'create': True}, name="album-create"),) 

En la vista album_list Quiero mostrar url para crear nuevos album_page álbum.

Encontré que tengo que usar el parámetro current_app de la función inversa para obtener la URL adecuada.

¿Pero cómo obtener esta current_app? Pensé que la respuesta es algo simple. Pero no puedo encontrarlo en la documentación de django.

Gracias, Nick

Respuesta

-3

Después de explorar este tema durante varios días, descubrí que no es natural montar la aplicación django más de una vez.

Hay implementación de patrón de aplicaciones conectables: http://github.com/nowells/django-pluggables. Parece demasiado complicado para mí.

Así que decidí mover la funcionalidad repetida a etiquetas personalizadas y plantillas duplicadas para cada uso de mi aplicación. Espero usar etiquetas personalizadas y ampliar la función. Ayúdame a seguir el principio DRY.

-4

creo que es lo que el marco es para sites.

+0

leí documentos que se sugieran. No creo que sea la respuesta correcta. De acuerdo con la documentación, el marco de sitios es útil cuando desea compartir información entre sitios, pero en mi caso solo hay un sitio. Técnicamente es posible implementar mi aplicación de fotos en diferentes subdominios, pero creo que es incorrecto crear dominios separados para cada instancia de aplicación reutilizable. – Nike

1

En sus direcciones URL, tiene una app_name diferente a pesar de que es la misma aplicación. Establezca app_name en la misma cosa y establezca namespace de forma única para cada instancia. p.ej.

urlpatterns = patterns('', 
(r'^carphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='car-photos')), 
(r'^userphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='profile-photos')),) 

A continuación, proporciona el argumento de current_app cuando se utiliza inversa. Ver http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse y http://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces

[editar] después de volver a leer su pregunta:

que no es necesario para proporcionar el argumento current_app si está utilizando la etiqueta {% url %}. Por lo que a mí respecta, accederá automáticamente a una variable de plantilla llamada current_app, que se establece automáticamente en función de la url coincidente.

+0

Intenté este código, y no resuelve el problema. Como descubrí, current_app es el argumento de Context o RequestContext que debo proporcionar de forma explícita. Y cómo conseguirlo es la pregunta de esta página. Por cierto, después de configurar el argumento de espacio de nombres, mis direcciones URL se rompen como se describe en http://code.djangoproject.com/ticket/11559 – Nike

10

Sé que esto es una pregunta bastante viejo ... pero creo que he encontrado una solución:

Como Will Hardy sugerido que tendrá que mantener app_name el mismo para ambos casos (o no define en absoluto , se aplicará de manera predeterminada a la aplicación en la que residen las URL incluidas). Definir un espacio de nombres separado para cada instancia de aplicación embargo:

urlpatterns = patterns('', 
    (r'^carphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='car-photos')), 
    (r'^userphotos/', include('webui.photos.urls', app_name="webui_photos", namespace='profile-photos')), 
) 

Ahora viene la parte un poco difícil de establecer la instancia aplicación activa en ese momento (espacio de nombres) en sus puntos de vista. Lo que significa que tiene que averiguar qué instancia de aplicación está activa y pasarla al RequestContext.

para encontrar la aplicación activa en ese momento, django.core.urlresolvers.resolve se puede utilizar:

r = resolve(request.path) 
r.app_name # the app name 
r.namespace # the the currently active instance 

por lo que tendrá que actualizar sus puntos de vista (esto supone el uso de los puntos de vista basados ​​clase) en consecuencia:

from django.core.urlresolvers import resolve 
from django.views.generic import TemplateView 


class AlbumCreateView(TemplateView): 
    template_name = 'path/to/my/template.html' 

    def render_to_response(self, context, **response_kwargs): 
     response_kwargs['current_app'] = resolve(self.request.path).namespace 
     return super(AlbumPageView, self).render_to_response(context, **response_kwargs) 

Ahora la etiqueta url automáticamente revertirá al espacio de nombres correcto y aún permitirá la reversión a un espacio de nombres de aplicación específico si es necesario:

{% url webui_photos:album-create %} {# returns the url for whatever app is current #} 
{% url car-photos:album-create %} 
{% url profile-photos:album-create %} 

Para invertir las direcciones URL en las vistas, la instancia de aplicación actual tiene que ser aprobada en forma manual:

reverse('webui_photos:album-create', current_app=resolve(self.request.path).namespace)) 
Cuestiones relacionadas