Quería hacer algo casi idéntico a la pregunta de OP (mesa y todo), estaba igualmente frustrado por la falta de cooperación de Django, y de forma similar terminé profundizando en la fuente para llegar a mi propia implementación. Lo que se me ocurrió es un poco diferente a la respuesta aceptada, y me gustó más porque estaba usando un simple {{ form.as_table }}
en mi plantilla y no quería tener que pasar por visible_fields
innecesariamente o codificar un botón de radio en mi plantilla que simplemente se parece a la implementación actual de Django (que podría cambiar). Esto es lo que hice en su lugar:
RadioInput y RadioFieldRenderer
Reproductor de Django RadioSelect
utiliza RadioFieldRenderer
para producir un generator de RadioInputs
, que haga el trabajo real de la prestación de los botones de radio. RadioSelect
parece tener una característica no documentada en la que puede pasarle un representador diferente al predeterminado, por lo que puede subclasificar ambos para obtener lo que desea OP.
from django import forms
from django.utils.safestring import mark_safe
class CustomTableRadioInput(forms.widgets.RadioInput):
# We can override the render method to display our table rows
def render(self, *args, **kwargs):
# default_html will hold the normally rendered radio button
# which we can then use somewhere in our table
default_html = super(CustomTableRadioInput, self).render(*args, **kwargs)
# Do whatever you want to the input, then return it, remembering to use
# either django.utils.safestring.mark_safe or django.utils.html.format_html
# ...
return mark_safe(new_html)
class CustomTableFieldRenderer(forms.widget.RadioFieldRenderer):
# Here we just need to override the two methods that yield RadioInputs
# and make them yield our custom subclass instead
def __iter__(self):
for i, choice in enumerate(self.choices):
yield CustomTableRadioInput(self.name, self.value,
self.attrs.copy(), choice, i)
def __getitem__(self, idx):
choice = self.choices[idx] # Let the IndexError propogate
return CustomTableRadioInput(self.name, self.value,
self.attrs.copy(), choice, idx)
Una vez hecho esto, sólo tenemos que contar el widget RadioSelect
utilizar nuestro intérprete personalizado cada vez que lo llamamos en algún lugar de nuestro código de formulario:
...
radio = forms.ChoiceField(widget=forms.RadioSelect(renderer=CustomTableFieldRenderer),
choices=...)
...
Y eso es todo!
hacer la nota que para usar esto en la plantilla, es probable que desee para recorrer el campo en lugar de llamar directamente, es decir esto:
<table>
<tbody>
{% for tr in form.radio %}
<tr>{{ tr }}</tr>
{% endfor %}
</tbody>
</table>
en lugar de esto:
<table>
<tbody>{{ form.radio }}</tbody>
</table>
Si hace esto último, intentará envolver sus elementos de tabla en <ul><li>...</li></ul>
.
Hola, si imprimo este ** {{field.name}} **, imprime todo el nombre de los campos, pero si lo usé en la condición '{% if field.name =" attributes "%}' o '{% if field.name = attributes%}' e intenta imprimir algo con el éxito de esta condición y luego no imprime nada significa que la condición devuelve false. Pero el nombre de campo que utilicé en esta condición es uno que se imprime ... ** ¿POR QUÉ? ** – Inforian
Tiene una sola = debería ser == –