Skip to content

Commit

Permalink
Merge pull request #593 from azmeuk/pr-530-month-field
Browse files Browse the repository at this point in the history
Implemented MonthField
  • Loading branch information
azmeuk authored May 28, 2020
2 parents 12020ba + 1040d0a commit ad3280e
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Unreleased
- Choices shortcut for :class:`~fields.core.SelectMultipleField`.
:issue:`603` :pr:`605`
- Forms can have form-level errors. :issue:`55` :pr:`595`
- Implemented :class:`~wtforms.fields.core.MonthField`. :pr:`530` :pr:`593`


Version 2.3.1
Expand Down
2 changes: 2 additions & 0 deletions docs/fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ namespace and can be overridden or modified just like any other widget.

.. autoclass:: DateField(default field arguments, format='%Y-%m-%d')

.. autoclass:: MonthField(default field arguments, format='%Y-%m')

.. autoclass:: TimeField(default field arguments, format='%H:%M')

.. autoclass:: DateTimeLocalField(default field arguments, format='%Y-%m-%d %H:%M:%S')
Expand Down
44 changes: 31 additions & 13 deletions docs/widgets.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
Widgets
=======
.. module:: wtforms.widgets

Widgets are classes whose purpose are to render a field to its usable
representation, usually XHTML. When a field is called, the default behaviour
Expand All @@ -15,17 +14,36 @@ recognize as not needing to be auto-escaped.
Built-in widgets
----------------

.. autoclass:: ListWidget
.. autoclass:: TableWidget
.. autoclass:: Input
.. autoclass:: TextInput()
.. autoclass:: PasswordInput
.. autoclass:: HiddenInput()
.. autoclass:: CheckboxInput()
.. autoclass:: FileInput()
.. autoclass:: SubmitInput()
.. autoclass:: TextArea
.. autoclass:: Select
.. autoclass:: wtforms.widgets.ListWidget
.. autoclass:: wtforms.widgets.TableWidget
.. autoclass:: wtforms.widgets.Input
.. autoclass:: wtforms.widgets.TextInput()
.. autoclass:: wtforms.widgets.PasswordInput
.. autoclass:: wtforms.widgets.HiddenInput()
.. autoclass:: wtforms.widgets.CheckboxInput()
.. autoclass:: wtforms.widgets.FileInput()
.. autoclass:: wtforms.widgets.SubmitInput()
.. autoclass:: wtforms.widgets.TextArea
.. autoclass:: wtforms.widgets.Select

HTML5 widgets
-------------

.. module:: wtforms.widgets.html5

.. autoclass:: wtforms.widgets.html5.ColorInput
.. autoclass:: wtforms.widgets.html5.DateTimeInput
.. autoclass:: wtforms.widgets.html5.DateTimeLocalInput
.. autoclass:: wtforms.widgets.html5.DateInput
.. autoclass:: wtforms.widgets.html5.EmailInput
.. autoclass:: wtforms.widgets.html5.MonthInput
.. autoclass:: wtforms.widgets.html5.NumberInput
.. autoclass:: wtforms.widgets.html5.RangeInput
.. autoclass:: wtforms.widgets.html5.SearchInput
.. autoclass:: wtforms.widgets.html5.TelInput
.. autoclass:: wtforms.widgets.html5.TimeInput
.. autoclass:: wtforms.widgets.html5.URLInput
.. autoclass:: wtforms.widgets.html5.WeekInput

Widget-Building Utilities
-------------------------
Expand All @@ -34,7 +52,7 @@ These utilities are used in WTForms widgets to help render HTML and also in
order to work along with HTML templating frameworks. They can be imported for
use in building custom widgets as well.

.. autofunction:: html_params
.. autofunction:: wtforms.widgets.html_params

WTForms uses `MarkupSafe`_ to escape unsafe HTML characters before
rendering. You can mark a string using :class:`markupsafe.Markup` to
Expand Down
11 changes: 11 additions & 0 deletions src/wtforms/fields/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"SelectMultipleField",
"StringField",
"TimeField",
"MonthField",
)


Expand Down Expand Up @@ -898,6 +899,16 @@ def process_formdata(self, valuelist):
raise ValueError(self.gettext("Not a valid time value"))


class MonthField(DateField):
"""
Same as DateField, except represents a month, stores a `datetime.date`
with `day = 1`.
"""

def __init__(self, label=None, validators=None, format="%Y-%m", **kwargs):
super().__init__(label, validators, format, **kwargs)


class FormField(Field):
"""
Encapsulate a form as a field in another form.
Expand Down
8 changes: 8 additions & 0 deletions src/wtforms/fields/html5.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ class TimeField(core.TimeField):
widget = widgets.TimeInput()


class MonthField(core.MonthField):
"""
Represents an ``<input type="month">``.
"""

widget = widgets.MonthInput()


class DateTimeLocalField(core.DateTimeField):
"""
Represents an ``<input type="datetime-local">``.
Expand Down
24 changes: 24 additions & 0 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from wtforms.fields import IntegerField
from wtforms.fields import IntegerRangeField
from wtforms.fields import Label
from wtforms.fields import MonthField
from wtforms.fields import MultipleFileField
from wtforms.fields import PasswordField
from wtforms.fields import RadioField
Expand Down Expand Up @@ -811,6 +812,29 @@ def test_failure(self):
assert form.a.process_errors[0] == "Not a valid date value"


class TestMonthField:
class F(Form):
a = MonthField()
b = MonthField(format="%m/%Y")

def test_basic(self):
d = date(2008, 5, 1)
form = self.F(DummyPostData(a=["2008-05"], b=["05/2008"]))

assert d == form.a.data
assert "2008-05" == form.a._value()

assert d == form.b.data

def test_failure(self):
form = self.F(DummyPostData(a=["2008-bb"]))

assert not form.validate()
assert 1 == len(form.a.process_errors)
assert 1 == len(form.a.errors)
assert "Not a valid date value" == form.a.process_errors[0]


class TestTimeField:
class F(Form):
a = TimeField()
Expand Down

0 comments on commit ad3280e

Please sign in to comment.