From 36c404788d0e217af3137053875c1036782b8b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Fri, 21 Mar 2025 10:00:00 +0100 Subject: [PATCH 1/5] Document how to customize SplitPhoneNumberField fields --- docs/reference.rst | 10 ++++++++++ phonenumber_field/formfields.py | 10 ++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index dea3d60b..23ffd0e6 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -168,6 +168,14 @@ A :class:`~django.forms.MultiValueField` that offers: - a ```` to enter the phone number. +To customize each field, subclass +:class:`~phonenumber_field.formfields.SplitPhoneNumberField` and override: + +- :func:`~phonenumber_field.formfields.SplitPhoneNumberField.prefix_field` + for the phone number prefix field, +- :func:`~phonenumber_field.formfields.SplitPhoneNumberField.number_field` + for the phone number field. + This widget uses an example phone number from the selected region for the ``invalid`` key in :attr:`~django.forms.Field.error_messages`, when the region choice is valid. @@ -180,6 +188,8 @@ To customize the dynamic message, use .. autoclass:: phonenumber_field.formfields.SplitPhoneNumberField .. automethod:: __init__ + .. automethod:: prefix_field + .. automethod:: number_field .. automethod:: invalid_error_message Usage diff --git a/phonenumber_field/formfields.py b/phonenumber_field/formfields.py index 8737b5b0..67ce537c 100644 --- a/phonenumber_field/formfields.py +++ b/phonenumber_field/formfields.py @@ -136,13 +136,19 @@ def __init__(self, *, initial=None, region=None, widget=None, **kwargs): def prefix_field(self): """ - Customize the phone number prefix field. + Returns the default :class:`~django.forms.Field` for the phone + number prefix field. + + Use this hook to set widget attributes or update the field definition. """ return PrefixChoiceField() def number_field(self): """ - Customize the phone number input field. + Returns the default :class:`~django.forms.Field` for the phone + number field. + + Use this hook to set widget attributes or update the field definition. """ number_field = CharField() number_field.widget.input_type = "tel" From 5c38ae6b342f0ddd262da1979b83bf0c52d94bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Fri, 4 Apr 2025 09:41:58 +0200 Subject: [PATCH 2/5] Import django.forms globally in docs Avoid repeating from django import forms in all example, and django.forms should be clear enough to understand where the import is coming from. --- docs/reference.rst | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index 23ffd0e6..6a8cce31 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -117,10 +117,9 @@ Usage .. doctest:: formfield - >>> from django import forms >>> from phonenumber_field.formfields import PhoneNumberField - >>> class PhoneForm(forms.Form): + >>> class PhoneForm(django.forms.Form): ... number = PhoneNumberField(region="CA") ... @@ -197,10 +196,9 @@ Usage .. doctest:: SplitPhoneNumberField - >>> from django import forms >>> from phonenumber_field.formfields import SplitPhoneNumberField - >>> class PhoneForm(forms.Form): + >>> class PhoneForm(django.forms.Form): ... number = SplitPhoneNumberField() ... @@ -233,13 +231,13 @@ Usage # Limiting country choices. >>> class DemoSplitPhoneNumberField(SplitPhoneNumberField): ... def prefix_field(self): - ... return forms.ChoiceField(choices=[ + ... return django.forms.ChoiceField(choices=[ ... ("", "---------"), ... ("CA", "Canada"), ... ("FR", "France"), ... ]) ... - >>> class LimitedCountryPhoneForm(forms.Form): + >>> class LimitedCountryPhoneForm(django.forms.Form): ... number = DemoSplitPhoneNumberField() ... >>> form = LimitedCountryPhoneForm() @@ -265,7 +263,7 @@ Usage # Pre-selecting a country. - >>> class FrenchPhoneForm(forms.Form): + >>> class FrenchPhoneForm(django.forms.Form): ... number = DemoSplitPhoneNumberField(region="FR") ... @@ -317,10 +315,9 @@ Usage .. doctest:: fallbackwidget - >>> from django import forms >>> from phonenumber_field.formfields import PhoneNumberField - >>> class CanadianPhoneForm(forms.Form): + >>> class CanadianPhoneForm(django.forms.Form): ... # RegionalPhoneNumberWidget is the default widget. ... number = PhoneNumberField(region="CA") ... From 275d445e0ee282ce2c607ff91648ce22c69f750d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Fri, 4 Apr 2025 09:43:53 +0200 Subject: [PATCH 3/5] docs: Split example for SplitPhoneNumerField Another example is coming, and it becomes hard to identify what examples are provided. --- docs/reference.rst | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index 6a8cce31..45de1590 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -194,7 +194,10 @@ To customize the dynamic message, use Usage ~~~~~ -.. doctest:: SplitPhoneNumberField +Simple +...... + +.. doctest:: SplitPhoneNumberField.basic >>> from phonenumber_field.formfields import SplitPhoneNumberField @@ -228,7 +231,13 @@ Usage - # Limiting country choices. +Limiting country choices +........................ + +.. doctest:: SplitPhoneNumberField.country_choices + + >>> from phonenumber_field.formfields import SplitPhoneNumberField + >>> class DemoSplitPhoneNumberField(SplitPhoneNumberField): ... def prefix_field(self): ... return django.forms.ChoiceField(choices=[ @@ -262,7 +271,22 @@ Usage - # Pre-selecting a country. +Pre-selecting a country +....................... + +.. doctest:: SplitPhoneNumberField.preselecting_country + + >>> from phonenumber_field.formfields import SplitPhoneNumberField + + >>> class DemoSplitPhoneNumberField(SplitPhoneNumberField): + ... def prefix_field(self): + ... return django.forms.ChoiceField(choices=[ + ... ("", "---------"), + ... ("CA", "Canada"), + ... ("FR", "France"), + ... ]) + ... + >>> class FrenchPhoneForm(django.forms.Form): ... number = DemoSplitPhoneNumberField(region="FR") ... From 10eea1f23a9ade1b7f781772c6b5777204218939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Fri, 4 Apr 2025 10:04:24 +0200 Subject: [PATCH 4/5] docs: Customize SplitPhoneNumberField widgets attrs --- docs/reference.rst | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/reference.rst b/docs/reference.rst index 45de1590..2df24b1a 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -313,6 +313,53 @@ Pre-selecting a country +Customizing widget attrs +........................ + +.. doctest:: SplitPhoneNumberField.preselecting_country + + >>> from phonenumber_field.formfields import SplitPhoneNumberField + + >>> class DemoSplitPhoneNumberField(SplitPhoneNumberField): + ... def prefix_field(self): + ... return django.forms.ChoiceField(choices=[ + ... ("", "---------"), + ... ("CA", "Canada"), + ... ("FR", "France"), + ... ]) + ... + ... def number_field(self): + ... number_field = super().number_field() + ... number_field.widget.attrs["class"] = "form-control" + ... return number_field + ... + + >>> class BootstrapPhoneForm(django.forms.Form): + ... number = DemoSplitPhoneNumberField() + ... + + >>> form = BootstrapPhoneForm() + >>> print_html(form.as_div()) +
+
+ + Number: + + + +
+
+ Widgets ------- From e17c66283aaca276dd5870194541b6883ffe490d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Fri, 4 Apr 2025 10:12:08 +0200 Subject: [PATCH 5/5] docs: Adapt
    to django output --- docs/reference.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index 2df24b1a..8993355d 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -146,12 +146,12 @@ Usage -
      +
      • Enter a valid phone number (e.g. (506) 234-5678) or a number with an international call prefix.
      - + .. note:: Because the PhoneNumberField specifies a region, the example number