Pregunta

Tengo un modelo de Django con una gran cantidad de campos y más de 20000 filas de tabla.Para facilitar las URL legibles por humanos y la capacidad de dividir la lista grande en sublistas arbitrarias, me gustaría tener una URL similar a esta:

/browse/<name1>/<value1>/<name2>/<value2>/ .... etc ....

donde 'nombre' se asigna a un atributo del modelo y 'valor' es el criterio de búsqueda para ese atributo.Cada "nombre" será tratado como una categoría para devolver subconjuntos de las instancias del modelo donde coinciden las categorías.

Ahora, esto podría manejarse con parámetros GET, pero prefiero URL más legibles tanto por el bien del usuario como por los motores de búsqueda.Estos subconjuntos de URL se incrustarán en cada página que muestre este modelo, por lo que parece que vale la pena el esfuerzo de crear URL bonitas.

Idealmente, cada par de nombre/valor se pasará a la función de vista como un parámetro llamado name1, name2, etc.Sin embargo, no creo que sea posible definir patrones con nombre a través del texto coincidente de una expresión regular.¿Me equivoco ahí?

Entonces, parece que necesito hacer algo como esto:

urlpatterns = patterns('',
    url(r'^browse/(?:([\w]+)/([\w]+)/)+$', 'app.views.view', name="model_browse"),
)

Parece que esto debería coincidir con cualquier conjunto de dos pares de nombre/valor.Si bien coincide con éxito, solo pasa el par apellido/valor como parámetros a la función de vista.Mi conjetura es que cada coincidencia sobrescribe la coincidencia anterior.Suponiendo que el contenido (?:...)+ lo está causando, probé un patrón repetitivo simple:

urlpatterns = patterns('',
    url(r'^browse/([\w]+/)+$', 'app.views.view', name="model_browse"),
)

...y tengo el mismo problema, pero esta vez *args Solo incluye el último patrón coincidente.

¿Es esto una limitación del despachador de URL de Django y/o del soporte de expresiones regulares de Python?Parece que cualquiera de estos métodos debería funcionar.¿Hay alguna manera de lograr esto sin codificar cada posible atributo del modelo en la URL como un patrón opcional (.*)?

¿Fue útil?

Solución

Una posibilidad que podría considerar es hacer coincidir la cadena completa de valores posibles dentro de la parte del patrón de URL y extraer las piezas específicas dentro de su vista. Como ejemplo:

urlpatterns = patterns('',
    url(r'^browse/(?P<match>.+)/$', 'app.views.view', name='model_browse'),
)

def view(request, match):
    pieces = match.split('/')
    # even indexed pieces are the names, odd are values
    ...

No hay promesas sobre la expresión regular que utilicé, pero creo que entiendes lo que quiero decir.

(Editado para tratar de corregir la expresión regular).

Otros consejos

Estoy de acuerdo con Adam, pero creo que el patrón en urls.py debería ser:

... r'^browse/(?P<match>.+)/$' ...

La '\ w' solo coincidirá con los caracteres de 'palabra', pero la '.' coincidirá con cualquier cosa.

La misma respuesta me llegó mientras leía la pregunta.

Creo que la vista model_browse es la mejor manera de ordenar los parámetros de consulta y usarla como un enrutador genérico.

Creo que la respuesta de Adam es más genérica que mi solución, pero si desea utilizar una cantidad fija de argumentos en la URL, también puede hacer algo como esto:

El siguiente ejemplo muestra cómo obtener todas las ventas de un día para una ubicación ingresando el nombre de la store y el year, month y day.

URL.py:

urlpatterns = patterns('',
    url(r'^baseurl/location/(?P<store>.+)/sales/(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])/$', views.DailySalesAtLocationListAPIView.as_view(), name='daily-sales-at-location'),
)

Alternativamente, también puedes usar la identificación de la tienda cambiando (?P<store>.+) a (?P<store>[0-9]+).Tenga en cuenta que location y sales No hay palabras clave, solo mejoran la legibilidad de la URL.

vistas.py

class DailySalesAtLocationListAPIView(generics.ListAPIView):
    def get(self, request, store, year, month, day):
        # here you can start using the values from the url
        print store
        print year
        print month
        print date

        # now start filtering your model

¡Espero que ayude a alguien!

Atentamente,

Miguel

Tengo una solución alternativa, que no es muy diferente de la anterior pero es más refinada:

url(r'^my_app/(((list\/)((\w{1,})\/(\w{1,})\/(\w{1,3})\/){1,10})+)$'

He usado parámetros de URL sin nombre y un expresiones regulares repetitivas. No obtener & Quot; no es una expresión regular válida: repetición múltiple & Quot; coloco una palabra al principio de la lista.

Todavía estoy trabajando en la vista que recibe la lista. Pero creo que pasaré por los args o los kwargs ... No puedo decirlo exactamente.

Mis 2 centavos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top