Django BooleanField como botões de rádio?

votos
53

Existe um widget no Django 1.0.2 para renderizar um models.BooleanFieldcomo dois botões de rádio em vez de uma caixa de seleção?

Publicado 12/05/2009 em 21:21
fonte usuário
Em outras línguas...                            


10 respostas

votos
84

Django 1.2 adicionou os "widgets" opção Meta para modelforms:

Em seu models.py, especifique as "escolhas" para o seu campo booleano:

BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))

class MyModel(models.Model):
    yes_or_no = models.BooleanField(choices=BOOL_CHOICES)

Então, em sua forms.py, especifique o widget RadioSelect para esse campo:

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

Eu testei isso com um db SQLite, que também armazena booleans como 1/0 valores, e parece funcionar muito bem sem uma função coerce personalizado.

Respondeu 18/10/2010 em 17:16
fonte usuário

votos
59

Você poderia fazer isso, substituindo a definição de campo no 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
Respondeu 12/05/2009 em 21:42
fonte usuário

votos
30

Modificando a resposta de Daniel Roseman um pouco, você pode corrigir o bool ( "Falso") = True problema de forma sucinta apenas usando ints em vez disso:

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
Respondeu 10/09/2009 em 16:31
fonte usuário

votos
9

No Django 1.6, o seguinte trabalhou para mim:

class EmailSettingsForm(ModelForm):

    class Meta:
        model = EmailSetting
        fields = ['setting']
        widgets = {'setting': RadioSelect(choices=[
            (True, 'Keep updated with emails.'),
            (False, 'No, don\'t email me.')             
        ])}
Respondeu 19/08/2014 em 14:27
fonte usuário

votos
8

Aqui é a abordagem mais simples que eu poderia encontrar (estou usando Django 1.5):

class MyModelForm(forms.ModelForm):
    yes_no = forms.BooleanField(widget=RadioSelect(choices=[(True, 'Yes'), 
                                                            (False, 'No')]))
Respondeu 02/07/2014 em 06:12
fonte usuário

votos
5

Aqui está uma função coerce rápida e suja usando lambda, que fica em torno do "Falso" -> Verdadeiro problema:

...
boolfield = forms.TypedChoiceField(coerce=lambda x: x and (x.lower() != 'false'),
...
Respondeu 26/05/2010 em 22:55
fonte usuário

votos
3

Uma outra solução:

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)
Respondeu 05/03/2013 em 14:12
fonte usuário

votos
3

Mesmo como resposta de @ eternicode, mas sem modificar o modelo:

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

    class Meta:
        model = MyModel
        widgets = {'boolfield': yes_no}

Eu acho que isso só funciona em Django 1.2+

Respondeu 12/01/2012 em 11:23
fonte usuário

votos
3

Como não há problema em resposta @ Daniel Roseman, bool ( 'False') -> É verdade, então agora eu tenho combinadas duas respostas aqui para fazer uma solução.

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

Agora isso vai funcionar :)

Respondeu 20/07/2011 em 14:42
fonte usuário

votos
3

Lembre-se também que o MySQL usa tinyint para booleana, então Verdadeiro / Falso são realmente 1/0. Eu usei esta função coerce:

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
Respondeu 18/06/2009 em 09:35
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more