urls - Incluyendo una cadena de consulta en una llamada django.core.urlresolvers reverse()
from django.core.urlresolvers import reverse_lazy (5)
Acabo de hacer mi propia función de utilidad como la que hice en la pregunta:
from django.utils.http import urlencode
def my_reverse(viewname, kwargs=None, query_kwargs=None):
"""
Custom reverse to add a query string after the url
Example usage:
url = my_reverse(''my_test_url'', kwargs={''pk'': object.id}, query_kwargs={''next'': reverse(''home'')})
"""
url = reverse(viewname, kwargs=kwargs)
if query_kwargs:
return u''%s?%s'' % (url, urlencode(query_kwargs))
return url
Intento revertir una URL con nombre e incluir una cadena de consulta en ella. Básicamente, he modificado la función de inicio de sesión y deseo enviar ?next=
in it.
Esto es lo que estoy haciendo ahora: reverse(name) + "?next=" + reverse(redirect)
Esto es lo que me gustaría hacer: reverse(name, kwargs = { ''next'':reverse(redirect) } )
Mi URL para la página de inicio de sesión (solo como un ejemplo) se ve así:
url(r''^login/'', custom_login, name = ''login''),
Entonces, ¿cómo modifico todo esto (o lo llamo) para incluir el siguiente sin tener que concatenarlo? Se siente como una solución dudosa en el mejor de los casos.
Creo que es mejor ajustar el método inverso de Django para exponer esta API. Aquí hay un código simple para hacerlo:
from django.core.urlresolvers import reverse as django_reverse
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
"""
Wrapper of django.core.urlresolvers.reverse that attaches arguments in kwargs as query string parameters
"""
if kwargs:
return ''%s?%s'' % (django_reverse(viewname, urlconf, args, None, prefix, current_app), /
''&''.join([''%s=%s'' % (k,v) for k,v in kwargs.items()]))
else:
return django_reverse(viewname, urlconf, args, kwargs, prefix, current_app)
Coloque este código en alguna utilidad o aplicación común que solo dependa de Django, luego, en lugar de importar django.core.urlresolvers.reverse solo importe myproject.myutils.urlresolvers.reverse
Estaba preocupado con la misma pregunta y encontré este link . Aparentemente, su solución no está mal diseñada en absoluto. De acuerdo con la discusión del ticket, Django no proporcionará esta funcionalidad.
Por otro lado, es usar su propia función para hacer esto, de una manera mucho más limpia. Aquí está el indicado en la discusión
from django.utils.http import urlencode
from django.core.urlresolvers import reverse as original_reverse
def reverse(*args, **kwargs):
get = kwargs.pop(''get'', {})
url = original_reverse(*args, **kwargs)
if get:
url += ''?'' + urlencode(get)
return url
En el caso de la pregunta, se puede usar de la siguiente manera
from [myfunctions] import reverse
...
reverse(''login'', get={next: reverse(redirect)})
No puede capturar parámetros GET en los confs url, por lo que su método es correcto.
Generalmente prefiero el formato de cadenas, pero es lo mismo.
"%s?next=%s" % (reverse(name), reverse(redirect))
http://docs.djangoproject.com/en/dev/topics/http/urls/#what-the-urlconf-searches-against
El URLconf busca contra la URL solicitada, como una cadena de Python normal. Esto no incluye los parámetros GET o POST, o el nombre de dominio.
Para mantener la consulta opcional, puede ajustar la función inversa de Django con su propia función que también maneja la consulta, lo que permite otro manejo adecuado de la función inversa.
Crear una solicitud adecuada: query_kwargs
cuenta que query_kwargs
es opcional, por lo que no tiene que enviarlo
# from a views in views.py
def sendingView(request, truckID, fleetSlug):
#in the GET or POST
return HttpResponseRedirect(reverse(''subAppName:urlViewName'',
kwargs={''anyPassedKawrgs'':goHere,…},
query_kwargs={''queries'': goHere}
))
# from a template in specificTemplate.html
<a class="nav-link" href="{% url ''subAppName:urlViewName'' kwarg1=kwarg1 kwarg2=kwarg2 … query_kwargs={''dict'':here} %}">Link</a>
#from a model in models.py
class Truck(models.Model):
name = models.CharField(…)
def get_absolute_wi_url(self):
return reverse(''subAppName:urlViewName'', kwargs={''kwarg1'':kwarg1,''kwarg2'':kwarg2})
En el archivo utils.py
(basado en docs ) para (1.11 y utils.py
posteriores)
-myMainApp
-apps
-static
...
-utils
-__init__.py
-utils.py
from django.core.urlresolvers import reverse as django_reverse
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None, query_kwargs=None):
"""
Wrapper of django.core.urlresolvers.reverse that attaches arguments in kwargs as query string parameters
"""
if query_kwargs:
return ''%s?%s'' % (django_reverse(viewname, urlconf, args, kwargs, current_app), /
''&''.join([''%s=%s'' % (k,v) for k,v in query_kwargs.items()]))
else:
return django_reverse(viewname, urlconf, args, kwargs, current_app)
En las urls conf urls.py
app_name = ''subAppName''
urlpatterns = [
url(r''^(?P<kawrg1>[a-zA-Z0-9]+)/(?P<kawrg2>[a-zA-Z0-9]+)/path/to/here/$'', views.urlViewFunctionName, name=''urlViewName''),
Y obteniendo acceso a la consulta
#in a view
def urlViewFunctionName(request, kwarg1, kwarg2):
if request.GET.get(''submittedData''):
submittedQuery = request.GET.get(''submittedData'')
else:
submittedQuery = None
return render(request, ''trucks/weeklyInspectionSuccess.html'', {
''truck'': truck,
''submittedQuery'': submittedQuery
})
#in a template
<div class="container">
Success for {{kwarg1}}
{{submittedQuery}}
</div>