specified has formularios form fields example django django-models django-forms

has - Django BooleanField como botones de radio?



post django (10)

Aquí hay una función de coerción rápida y sucia usando lambda, que evita el "Falso" -> Verdadero problema:

... boolfield = forms.TypedChoiceField(coerce=lambda x: x and (x.lower() != ''false''), ...

¿Hay un widget en Django 1.0.2 para representar un models.BooleanField como dos botones de opción en lugar de una casilla de verificación?


Como hay un problema en la respuesta de @Daniel Roseman, bool (''False'') -> True, entonces ahora he combinado dos respuestas aquí para hacer una solución.

def boolean_coerce(value): # value is received as a unicode string if str(value).lower() in ( ''1'', ''true'' ): return True elif str(value).lower() in ( ''0'', ''false'' ): return False return None class MyModelForm(forms.ModelForm): boolfield = forms.TypedChoiceField(coerce= boolean_coerce, choices=((False, ''False''), (True, ''True'')), widget=forms.RadioSelect ) class Meta: model = MyModel

Ahora esto funcionará :)


Django 1.2 ha agregado la opción Meta "widgets" para modelos:

En su models.py, especifique las "opciones" para su campo booleano:

BOOL_CHOICES = ((True, ''Yes''), (False, ''No'')) class MyModel(models.Model): yes_or_no = models.BooleanField(choices=BOOL_CHOICES)

Luego, en su forms.py, especifique el widget RadioSelect para ese campo:

class MyModelForm(forms.ModelForm): class Meta: model = MyModel widgets = { ''yes_or_no'': forms.RadioSelect }

He probado esto con un SQLite db, que también almacena booleanos como valores 1/0, y parece funcionar bien sin una función de coerción personalizada.


En Django 1.6, lo siguiente funcionó para mí:

class EmailSettingsForm(ModelForm): class Meta: model = EmailSetting fields = [''setting''] widgets = {''setting'': RadioSelect(choices=[ (True, ''Keep updated with emails.''), (False, ''No, don/'t email me.'') ])}


Este es el enfoque más simple que pude encontrar (estoy usando Django 1.5):

class MyModelForm(forms.ModelForm): yes_no = forms.BooleanField(widget=RadioSelect(choices=[(True, ''Yes''), (False, ''No'')]))


Lo mismo que la respuesta de @eternicode, pero sin modificar el modelo:

class MyModelForm(forms.ModelForm): yes_no = forms.RadioSelect(choices=[(True, ''Yes''), (False, ''No'')]) class Meta: model = MyModel widgets = {''boolfield'': yes_no}

Creo que esto solo funciona en Django 1.2+


Modificando un poco la respuesta de Daniel Roseman, podrías arreglar el bool ("False") = verdadero problema sucintamente con solo usar ints:

class MyModelForm(forms.ModelForm): boolfield = forms.TypedChoiceField(coerce=lambda x: bool(int(x)), choices=((0, ''False''), (1, ''True'')), widget=forms.RadioSelect ) class Meta: model = MyModel


Otra solución:

from django import forms from django.utils.translation import ugettext_lazy as _ def RadioBoolean(*args, **kwargs): kwargs.update({ ''widget'': forms.RadioSelect, ''choices'': [ (''1'', _(''yes'')), (''0'', _(''no'')), ], ''coerce'': lambda x: bool(int(x)) if x.isdigit() else False, }) return forms.TypedChoiceField(*args, **kwargs)


Puede hacer esto anulando la definición de campo en ModelForm:

class MyModelForm(forms.ModelForm): boolfield = forms.TypedChoiceField( coerce=lambda x: x == ''True'', choices=((False, ''False''), (True, ''True'')), widget=forms.RadioSelect ) class Meta: model = MyModel


También recuerde que MySQL usa tinyint para Boolean, por lo que True / False son en realidad 1/0. Usé esta función de coerción:

def boolean_coerce(value): # value is received as a unicode string if str(value).lower() in ( ''1'', ''true'' ): return True elif str(value).lower() in ( ''0'', ''false'' ): return False return None