setting help_text for each choice in a RadioSelect

后端 未结 2 1238
孤城傲影
孤城傲影 2021-02-08 19:26

I can set the help_text attribute on any form field, but is it possible to set help_text on the choices used for a RadioSelect()?

I\'d looking for a clean way to show so

相关标签:
2条回答
  • 2021-02-08 20:07

    Assuming you're using RadioSelect as a widget for forms.ChoiceField, you can do something like:

    choices = (('1', 'First help_text here'),
               ('2', 'Second help_text here'),
               ('3', 'Third help_text here'),
              )
    
    class MyForm(forms.Form):
        ...
        choice = forms.ChoiceField(widget = RadioSelect, choices = choices)
    

    This isn't a strict use of help_text but it should get the job done in most cases.

    0 讨论(0)
  • 2021-02-08 20:11

    @Rishabh is correct but I'll elaborate further as, at first glance, it doesn't appear to be the solution, although it is; or, at least, it can be kludged to get a useful effect without having to dive too deep into django forms.

    The second element of the tuple is presented inside the "label" tag - so any 'inline elements' are permissible; for example:

    The desired result

    Or something like it

    <ul>
      <li><label for="id_ticket_0">
          <input type="radio" id="id_ticket_0" value="PARTTIME" name="ticket"> 
          <em>Part Time</em> Valid on Friday Night and Saturday Only
      </label></li>
      <li><label for="id_ticket_1">
          <input type="radio" id="id_ticket_1" value="DAYTIME" name="ticket"> 
          <em>Casual</em> Valid on Saturday Only
      </label></li>
      <li><label for="id_ticket_2">
           <input type="radio" id="id_ticket_2" value="EARLYBIRD" name="ticket"> 
           <em>Early Bird</em> Valid on Friday, Saturday, and Sunday. $15 discount for booking before 1am January 3rd, 2011
       </label></li>
    </ul>
    

    The simple example

    The trick is to "mark_safe" the content of the description then stuff whatever you need into:

    from django.utils.safestring import mark_safe
    choices = (
      ('1', mark_safe(u'<em>One</em> | This is the first option. It is awesome')),
      ('2', mark_safe(u'<em>Two</em> | This is the second option. Good too.'))
    )
    

    The complex example

    So in this example we:

    1. assemble the choices into a list (any iterable structure will do)
    2. pass the structure to the form's init to create our radio options on the fly
    3. use a comprehension list to create an extended description for each radio option

    The data structure: Tickets are my own classes and they have attributes:

    • tickets.code - as in a ticket code
    • label - a pithy short description
    • help - a longer description

    But more about that later. First lets create some instances:

    from mymodule import ticket
    # so lets create a few
    fulltime = ticket('FULLTIME',160,'Full Time',
                  "Valid Monday to Friday inclusive")
    parttime = ticket('PARTTIME',110,'Full Time',
                  "Valid outside of business hours only")
    daytime  = ticket('DAYTIME',70,'Day Time',
                  "Valid only on weekends and public holidays")
    
    # and put them together in a list any way you like
    available_tickets = [fulltime, parttime, daytime]
    
    # now create the form
    OrderForm(tickets=available_tickets)
    

    That probably happened in your view code. Now to see what happens in the form

    class OrderForm(ModelForm):
    
        def __init__(self, *args, **kwargs):
            self.tickets = kwargs.pop('tickets')
            super(OrderForm, self).__init__(*args, **kwargs)
    
            choices = [(t.code, mark_safe(u'<em>%s</em> %s' % (t.label, t.help)))
                    for t in self.tickets]
            self.fields['ticket'] = forms.ChoiceField(
                choices = choices,
                widget  = forms.RadioSelect()
            )
    
    0 讨论(0)
提交回复
热议问题