tabla queryset modelos girls girl formulario form example dinamica python django django-models

python - queryset - tabla dinamica django



En Django, ¿cómo se filtra un QuerySet con búsquedas de campo dinámicas? (4)

Dada una clase:

from django.db import models class Person(models.Model): name = models.CharField(max_length=20)

¿Es posible, y de ser así cómo, tener un QuerySet que filtre basado en argumentos dinámicos? Por ejemplo:

# Instead of: Person.objects.filter(name__startswith=''B'') # ... and: Person.objects.filter(name__endswith=''B'') # ... is there some way, given: filter_by = ''{0}__{1}''.format(''name'', ''startswith'') filter_value = ''B'' # ... that you can run the equivalent of this? Person.objects.filter(filter_by=filter_value) # ... which will throw an exception, since `filter_by` is not # an attribute of `Person`.


La expansión del argumento de Python se puede usar para resolver este problema:

kwargs = { ''{0}__{1}''.format(''name'', ''startswith''): ''A'', ''{0}__{1}''.format(''name'', ''endswith''): ''Z'' } Person.objects.filter(**kwargs)

Esta es una expresión idiomática de Python muy común y útil.


Un ejemplo simplificado:

En una aplicación de encuesta de Django, quería una lista de selección HTML que mostrara usuarios registrados. Pero debido a que tenemos 5000 usuarios registrados, necesitaba una forma de filtrar esa lista en función de los criterios de consulta (como solo las personas que completaron un determinado taller). Para que el elemento de la encuesta sea reutilizable, necesitaba que la persona que crea la pregunta de la encuesta pueda adjuntar esos criterios a esa pregunta (no quiero codificar la consulta en la aplicación).

La solución que surgió no es 100% fácil de usar (requiere la ayuda de un técnico para crear la consulta) pero resuelve el problema. Al crear la pregunta, el editor puede ingresar un diccionario en un campo personalizado, por ejemplo:

{''is_staff'':True,''last_name__startswith'':''A'',}

Esa cadena se almacena en la base de datos. En el código de vista, vuelve como self.question.custom_query . El valor de eso es una cadena que se parece a un diccionario. Volvemos a convertirlo en un diccionario real con eval () y luego lo incluimos en el conjunto de preguntas con ** kwargs:

kwargs = eval(self.question.custom_query) user_list = User.objects.filter(**kwargs).order_by("last_name")


Una forma de búsqueda realmente compleja generalmente indica que un modelo más simple está tratando de encontrar su salida.

¿Cómo espera exactamente obtener los valores para el nombre y la operación de la columna? ¿De dónde obtienes los valores de ''name'' y ''startswith'' ?

filter_by = ''%s__%s'' % (''name'', ''startswith'')

  1. ¿Una forma de "búsqueda"? Vas a ... ¿Qué? - elegir el nombre de una lista de nombres? Elija la operación de una lista de operaciones? Si bien son abiertos, la mayoría de las personas lo encuentran confuso y difícil de usar.

    ¿Cuántas columnas tienen tales filtros? 6? 12? 18?

    • ¿Unos pocos? Una lista de selección compleja no tiene sentido. Algunos campos y algunas declaraciones if tienen sentido.
    • ¿Un número grande? Tu modelo no suena bien. Parece que el "campo" es en realidad la clave de una fila en otra tabla, no en una columna.
  2. Botones de filtro específicos. Espera ... Así es como funciona el administrador de Django. Los filtros específicos se convierten en botones. Y el mismo análisis que el anterior se aplica. Algunos filtros tienen sentido. Una gran cantidad de filtros generalmente significa una especie de primera violación de forma normal.

Una gran cantidad de campos similares a menudo significa que debería haber más filas y menos campos.