2011-04-22 24 views
13

Tengo una página de búsqueda que toma una variedad de parámetros. Quiero crear una nueva URL simplemente modificando un parámetro en la consulta. ¿Hay una manera fácil de hacer esto - algo así como:Alterar un parámetro de consulta en una url (Django)

# example request url 
http://example.com/search?q=foo&option=bar&option2=baz&change=before 

# ideal template code 
{% url_with change 'after' %} 

# resulting url 
http://example.com/search?q=foo&option=bar&option2=baz&change=after 

Así que esto tomaría la solicitud de URL, alterar un parámetro de consulta y luego regresar la nueva URL. Similar a lo que se puede lograr en el Catalizador Perl usando $c->uri_with({change => 'after'}).

¿O hay una manera mejor?

[Actualizado: referencias eliminado para paginación]

+0

reformular su pregunta, no está claro lo que quiere, y tratar de aceptar respuestas, que tienen una proporción de 0%. – manji

+1

He cambiado la pregunta para eliminar la referencia a la paginación, lo que pareció hacer saltar a la gente para dar la respuesta a una pregunta que no se hizo. Con gusto aceptará una buena respuesta tan pronto como haya una. – EvdB

Respuesta

9

Por lo tanto, escribir una etiqueta de plantilla en torno a este:

from urlparse import urlparse, urlunparse 
from django.http import QueryDict 

def replace_query_param(url, attr, val): 
    (scheme, netloc, path, params, query, fragment) = urlparse(url) 
    query_dict = QueryDict(query).copy() 
    query_dict[attr] = val 
    query = query_dict.urlencode() 
    return urlunparse((scheme, netloc, path, params, query, fragment)) 

Para una solución más completa, utilice Zachary Voase de URLObject 2, que está muy bien hecho.

+1

URLObject 2 parece ser exactamente lo que quiero (ed) - gracias – EvdB

0
+0

La pregunta es sobre la modificación de un solo parámetro en una url, no sobre paginar. – EvdB

+0

Lo siento. Cuando publiqué un enlace a paginación, me refiero a mirar el código, donde se construyen los parámetros GET. Lo siento, mi inglés – Igor

0

Además de los fragmentos citados por Mark Lavin, he aquí una lista de otras implementaciones que pude encontrar para una etiqueta de plantillas de Django, que modifica la cadena actual de consulta GET HTTP.

En djangosnippets.org:

En PyPI:

en GitHub:

15

lo hice esta etiqueta sencilla que no requiere ninguna biblioteca adicionales:

@register.simple_tag 
def url_replace(request, field, value): 

    dict_ = request.GET.copy() 

    dict_[field] = value 

    return dict_.urlencode() 

Uso como:

<a href="?{% url_replace request 'param' value %}"> 

Wil añadir 'parámetro' a la cadena de obtener la URL si no está ahí , o reemplazarlo con el nuevo valor si ya está allí.

También necesita que se proporcione la instancia de solicitud RequestContext a su plantilla desde su vista. Más información aquí:

http://lincolnloop.com/blog/2008/may/10/getting-requestcontext-your-templates/

+2

¡Agradable! Y cuando usa 'takes_context = True', la solicitud se puede leer a través de' context ['request'] ', ¡suponiendo que tiene el' RequestContext' en uso fuera del curso! – vdboor

+0

Dios mío, esto debería incluirse en Django. Solución muy elegante. –

+0

¿Es preferible usar 'dict _.__ setitem __ (campo, valor)' sobre 'dict_ [field] = value'? Django internamente usa ['__setitem__()'] (https://github.com/django/django/blob/1101467ce0756272a54f4c7bc65c4c335a94111b/django/http/request.py#L372) que hace una conversión 'bytes_to_text' – Medorator

8

mejoré solución de MPAF, para obtener la solicitud directamente de la etiqueta.

@register.simple_tag(takes_context = True) 
def url_replace(context, field, value): 
    dict_ = context['request'].GET.copy() 
    dict_[field] = value 
    return dict_.urlencode() 
0

Esto funcionó bastante bien para mí. Le permite establecer cualquier cantidad de parámetros en la URL. Funciona bien para un buscapersonas, mientras mantiene el resto de la cadena de consulta.

from django import template 
from urlobject import URLObject 

register = template.Library() 

@register.simple_tag(takes_context=True) 
def url_set_param(context, **kwargs): 
    url = URLObject(context.request.get_full_path()) 
    path = url.path 
    query = url.query 
    for k, v in kwargs.items(): 
     query = query.set_param(k, v) 
    return '{}?{}'.format(path, query) 

Luego, en la plantilla:

<a href="{% url_set_param page=last %}"> 
+0

¿Qué es 'URLobject'? ¿Tercero? –

Cuestiones relacionadas