Estoy tratando de crear una plantilla básica para mostrar los valores de campo de la instancia seleccionada, junto con sus nombres. Piense en ello como solo una salida estándar de los valores de esa instancia en formato de tabla, con el nombre del campo (verbose_name específicamente si se especifica en el campo) en la primera columna y el valor de ese campo en la segunda columna.
Por ejemplo, supongamos que tenemos la siguiente definición de modelo:
class Client(Model):
name = CharField(max_length=150)
email = EmailField(max_length=100, verbose_name="E-mail")
Me gustaría que se muestre en la plantilla de esta manera (suponga una instancia con los valores dados):
Field Name Field Value
---------- -----------
Name Wayne Koorts
E-mail waynes@email.com
Lo que intento lograr es poder pasar una instancia del modelo a una plantilla y poder iterar sobre ella dinámicamente en la plantilla, algo como esto:
<table>
{% for field in fields %}
<tr>
<td>{{ field.name }}</td>
<td>{{ field.value }}</td>
</tr>
{% endfor %}
</table>
¿Hay una forma ordenada y "aprobada por Django" de hacer esto? Parece una tarea muy común, y tendré que hacerlo a menudo para este proyecto en particular.
fuente
Puede usar el serializador de conjuntos de consultas a Python de Django.
Simplemente ponga el siguiente código en su vista:
Y luego en la plantilla:
Su gran ventaja es el hecho de que maneja campos de relación.
Para el subconjunto de campos intente:
fuente
verbose_name
pasar el campo?Finalmente encontré una buena solución para esto en la lista de correo de desarrollo :
En la vista agregue:
en la plantilla agregue:
fuente
FooForm
es unModelForm
, ¿no sería más fácil hacer simplementeFooForm(instance=Foo.objects.get(pk=object_id)))
:?A la luz del lanzamiento de Django 1.8 (y la formalización de la API Modelo _meta) , pensé que actualizaría esto con una respuesta más reciente.
Asumiendo el mismo modelo:
Django <= 1.7
Django 1.8+ (Modelo formalizado _meta API)
En el siguiente ejemplo, utilizaremos el método formalizado para recuperar todas las instancias de campo de un modelo a través de
Client._meta.get_fields()
:En realidad, se me ha señalado que lo anterior está un poco por la borda para lo que se necesitaba (¡estoy de acuerdo!). Simple es mejor que complejo. Estoy dejando lo anterior como referencia. Sin embargo, para mostrar en la plantilla, el mejor método sería usar un ModelForm y pasar en una instancia. Puede iterar sobre el formulario (equivalente a iterar sobre cada uno de los campos del formulario) y usar el atributo label para recuperar el verbose_name del campo modelo, y usar el método value para recuperar el valor:
Ahora, representamos los campos en la plantilla:
fuente
Aquí hay otro enfoque utilizando un método modelo. Esta versión resuelve los campos de lista de selección / elección, omite los campos vacíos y le permite excluir campos específicos.
Luego en tu plantilla:
fuente
except User.DoesNotExist:
?_meta.get_fields()
hasta que pueda probarlo.Ok, sé que es un poco tarde, pero como me topé con esto antes de encontrar la respuesta correcta, alguien más podría hacerlo.
De los documentos de django :
fuente
ordering = ['-id']
enclass Meta:
su objeto enmodels.py
. 2. luego useBlog.objects.filter(name__startswith='Beatles').values()[0]
model
objeto, volvería a presionar la base de datos solo para obtener los campos. ¿Alguna forma de evitar eso?Puede usar el
values()
método de aqueryset
, que devuelve un diccionario. Además, este método acepta una lista de campos para subconjuntos. Elvalues()
método no funcionaráget()
, por lo que debe usarlofilter()
(consulte la API de QuerySet ).En
view
...En
detail.html
...Para una colección de instancias devueltas por filtro:
En detalle.html ...
fuente
table
, así que necesito cadakey
s en ath
. ¿Cómo hago eso sin bucles? Simplemente tome cualquier instancia de objeto e iterar a través de él parakey
s? Actualmente estoy pasandomodel_to_dict(Model())
por separado para elth
, pero creo que es una instanciación de objeto innecesaria.get_object
en la vista de detalle (destrozada debido a la limitación del código en línea en los comentarios, y no creo que esto sea suficiente para su propia respuesta teniendo en cuenta cuán saturado es este hilo):def get_object(self, **kwargs): obj = super().get_object(**kwargs) obj = obj.__class__.objects.filter(pk=obj.pk).values()[0] return obj
obj.get_absolute_url
a esta lista sin duplicar las filas?Solía https://stackoverflow.com/a/3431104/2022534 pero sustituye model_to_dict de Django () con este para ser capaz de manejar ForeignKey:
Tenga en cuenta que lo he simplificado bastante eliminando las partes del original que no necesitaba. Es posible que desee volver a ponerlos.
fuente
Puede hacer que un formulario haga el trabajo por usted.
Luego en la plantilla:
fuente
DetailView
) funciona bien para mí. Sin embargo, es posible que desee utilizar enfield.label
lugar defield.name
.Realmente debería haber una forma integrada de hacer esto. Escribí esta utilidad
build_pretty_data_view
que toma un objeto modelo y una instancia de formulario (un formulario basado en su modelo) y devuelve aSortedDict
.Los beneficios de esta solución incluyen:
SortedDict
.exclude()
lista de nombres de campo para excluir ciertos campos.Meta: exclude()
, pero aún desea devolver los valores, agregue esos campos a laappend()
lista opcional .Para usar esta solución, primero agregue este archivo / función en algún lugar, luego impórtelo a su
views.py
.utils.py
Así que ahora en tu
views.py
podrías hacer algo como estoAhora en su
my-template.html
plantilla puede iterar sobre los datos así ...Buena suerte. ¡Espero que esto ayude a alguien!
fuente
Debajo está el mío, inspirado en el shacker's
get_all_fields
. Obtiene un dict de una instancia de modelo, si encuentra un campo de relación, entonces asigne el valor del campo un dict recursivamente.Esta función se utiliza principalmente para volcar una instancia de modelo en datos json:
fuente
En lugar de editar cada modelo, recomendaría escribir una etiqueta de plantilla que devolverá todos los campos de cualquier modelo dado.
Cada objeto tiene una lista de campos
._meta.fields
.Cada objeto de campo tiene un atributo
name
que devolverá su nombre y el métodovalue_to_string()
que se proporciona con su modeloobject
devolverá su valor.El resto es tan simple como se dice en la documentación de Django .
Aquí está mi ejemplo de cómo podría ser esta etiqueta de plantilla:
fuente
Sí, no es bonito, tendrás que hacer tu propio envoltorio. Eche un vistazo a la aplicación de búsqueda de datos integrada , que tiene todas las funcionalidades que realmente necesita.
fuente
Esto puede considerarse un hack, pero lo he hecho antes de usar modelform_factory para convertir una instancia de modelo en un formulario.
La clase Form tiene mucha más información dentro que es muy fácil de recorrer y servirá para el mismo propósito a expensas de un poco más de gastos generales. Si los tamaños de su conjunto son relativamente pequeños, creo que el impacto en el rendimiento sería insignificante.
La única ventaja, además de la conveniencia, es que puede convertir fácilmente la tabla en una cuadrícula de datos editable en una fecha posterior.
fuente
Se me ocurrió el siguiente método, que funciona para mí porque en todos los casos el modelo tendrá un ModelForm asociado.
Aquí hay un extracto de la plantilla que estoy usando para esta vista en particular:
Lo bueno de este método es que puedo elegir plantilla por plantilla el orden en que me gustaría mostrar las etiquetas de campo, utilizando la tupla que se pasa a GetModelData y especificando los nombres de campo. Esto también me permite excluir ciertos campos (por ejemplo, una clave externa de usuario) ya que solo los nombres de campo pasados a través de la tupla se integran en el diccionario final.
No voy a aceptar esto como la respuesta porque estoy seguro de que a alguien se le ocurre algo más "Djangonic" :-)
Actualización: estoy eligiendo esto como la respuesta final porque es el más simple de los dados que hace lo que necesito. Gracias a todos los que aportaron respuestas.
fuente
Solución Django 1.7 para mí:
Hay variables que son exactas a la pregunta, pero definitivamente deberías poder diseccionar este ejemplo
La clave aquí es usar
.__dict__
el modeloviews.py :
plantilla :
en la plantilla utilicé un filtro para acceder al campo en el dict
filtros.py :
fuente
Estoy usando esto, https://github.com/miracle2k/django-tables .
fuente
Este enfoque muestra cómo usar una clase como ModelForm de django y una etiqueta de plantilla como {{form.as_table}}, pero que toda la tabla parezca salida de datos, no un formulario.
El primer paso fue subclasificar el widget TextInput de django:
Luego subclasifiqué el ModelForm de django para cambiar los widgets predeterminados por versiones de solo lectura:
Esos fueron los únicos widgets que necesitaba. Pero no debería ser difícil extender esta idea a otros widgets.
fuente
Solo una edición de @wonder
Deje que Django maneje todos los otros campos que no sean los campos relacionados. Siento que es mas estable
fuente
Echa un vistazo a la aplicación django-etc . Tiene una
model_field_verbose_name
etiqueta de plantilla para obtener el nombre detallado del campo de las plantillas: http://django-etc.rtfd.org/en/latest/models.html#model-field-template-tagsfuente
Acabo de probar algo como esto en shell y parece hacer su trabajo:
Tenga en cuenta que si desea una representación str () para objetos extraños, debe definirla en su método str . A partir de eso, tiene un dict de valores para el objeto. Entonces puedes renderizar algún tipo de plantilla o lo que sea.
fuente
Django> = 2.0
Añadir
get_fields()
a sumodels.py
:Entonces llámalo como
object.get_fields
en tutemplate.html
:fuente
fuente