Fields reference ================ Single value input fields -------------------------- Morf includes many single value input fields: :class:`~morf.fields.Str`, :class:`~morf.fields.Int`, :class:`~morf.fields.Decimal`, :class:`~morf.fields.Time`, :class:`~morf.fields.Date`, :class:`~morf.fields.Datetime`, and :class:`~morf.fields.Bool`. These all take a single input value from the user and convert it to the destination type. Date and time fields -------------------- Specify the date format using the format argument:: starts_at = fields.Date(format='%d/%m/%Y') opening_time = fields.Time(format='%H:%M') next_reminder = fields.DateTime(format='%Y-%m-%d %H:%M:%S') If a user supplied date can't be parsed using the given format, these fields fall back on `python-dateutil ` to parse the input. If you expect European style dates to be given you will probably want to specify ``dayfirst=True``:: starts_at = fields.Date(format='%d/%m/%Y', dayfirst=True) Special field types ------------------- fields.Constant ~~~~~~~~~~~~~~~ Not modifiable by the user, a :class:`~morf.fields.Constant` field passes a known value through to the submitted data dict:: class MorfConBookingForm(BookingForm): event_name = fields.Constant('MorfCon 2014') fields.Hidden ~~~~~~~~~~~~~ :class:`~morf.fields.Hidden` fields are not displayed to the user, and rendered as ```` elements. Starting from version 0.2.5 you can also supply a ``hidden`` argument to any other field type and it will be rendered as a ```` element with no label. fields.ListOf ~~~~~~~~~~~~~ :class:`morf.fields.ListOf` fields represent a list of other fields. These can be any field type (this includes instances of :class:`morf.form.Form`, which can act as fields). When rendered, a :class:`~morf.fields.ListOf` field will show one control per item in the bound input, plus optional spare empty fields for the user to add more items to the collection. Set ``spare``, ``min`` and ``max`` when constructing a :class:`~morf.fields.ListOf` field to control this, eg:: team_members = fields.ListOf(PlayerForm(), label='Players', min=4, spare=4, max=11) Choice fields ~~~~~~~~~~~~~ Choice fields represent a choice from a fixed list of possiblities Choice fields need to be passed a list of choices. This can be a list, a callable returning a list or the name of a method on the form that returns a list:: def get_countries(): return [('gb', 'United Kingdom'), ('fr', 'France'), ('de', 'Germany')] class MyForm(HTMLForm): title = fields.Choice(choices=['Mr', 'Mrs', 'Miss']) country = fields.Choice(choices=get_countries) year = fields.Choice(choices='year_choices') def year_choices(self): current_year = date.today().year return range(current_year, current_year - 100, -1) The list of choices should be in one of the following formats: 1. A list of items to be used both as values and labels, eg ``['red', 'green', 'blue']`` 2. A list of (value, label) pairs, eg ``[('#ff0000', 'Red'), ('#00ff00', 'Green'), ('#0000ff', 'Blue')]`` The list may also contain one or more :class:`~morf.choices.OptGroup`. In an HTML select widget these would be rendered using the ```` element:: even_numbers = [(2, 'Two'), (4, 'Four'), (6, 'Six')] odd_numbers = [(1, 'One'), (3, 'Three'), (5, 'Five')] number_choices = [('Even numbers', OptGroup(even_numbers)), ('Odd numbers', OptGroup(odd_numbers))] Choice fields require that the input value is a valid selection from the list of choices. Set ``validate_choices=False`` to disable this:: donation_amount = fields.Choice(choices=[(10, '10€'), (20, '20€')], validate_choices=False) Choice fields are keyed on the json encoded representation of the value. The ``value_mapper`` argument can override this. When rendered in HTML forms choice values must be converted to strings, and then back again when the form is submitted and processed. The default strategy is to convert your choice keys to a JSON representation. This handles the common cases of strings and integer keys well (and also ``None``). An alternative implementation is offered, which adds a key based on a simple indexing of the items based on their position in the list. For example, the choices:: [('11:00', 'Elevenses'), ('13:00', 'Lunch time'), ('16:00', 'Tea time')] Would result in options indexed as follows:: When a user selects for example value ``2`` (Tea time), morf looks up the index and populates the field with the original object, in this case ``16:00`` The advantage with this strategy is that object identity is preserved. You can use any object as a value (perhaps a `:class:datetime.time` object in this case) and your form field will be populated with the very same object, thus elimating all the tedious mucking about converting values to strings and back again. However while this sounds neat, in practice there are major disadvantages: - It's fragile in the case that the list of values changes. - It's hard to test — to create test values for a choice field you have to know the index of the value you want. - It's hard to generate values for the field from other parts of your application (eg imagine a search form has a 'category' choice. Now you can't easily generate search URLs with ``category=...`` in the querystring) To enable this behaviour use the ``mapper`` argument when creating the widget:: from morf import fields, widgets choicefield = fields.Choice( choices=['a', 'b', 'c'], widget=widgets.Select(mapper=widgets.IndexChoiceMapper()) fields.MultipleChoice ~~~~~~~~~~~~~~~~~~~~~ A variant of the normal choice field, :class:`~morf.fields.MultipleChoice` fields allow the user to select more than one choice. By default :class:`~morf.fields.MultipleChoice` fields are rendered using the :class:`morf.widgets.CheckboxGroup` widget. Fields API reference --------------------- .. automodule:: morf.fields :members: Choices API reference --------------------- .. automodule:: morf.choices :members: