Skip to content

Conversation

bblanchon
Copy link
Contributor

Hi @stefanfoulis,

Thank you very much for this indispensable library ❤️

I recently noticed a bug when PHONENUMBER_DEFAULT_FORMAT is set to NATIONAL.
I initially wanted to open an issue, but when I tried to create a repro, I realized I should open a Pull Request instead.

Description of the bug

When PHONENUMBER_DEFAULT_FORMAT is set to NATIONAL, you used to get a validation error after setting a PhoneNumberField to a phone number that is not in the default region.

tm = models.TestModel()
tm.phone = "+41 52 424 2424"
tm.full_clean()  # raises ValidationError "The phone number entered is not valid"

This was because PhoneNumberField didn't override to_python(), so CharField.to_python() was called and returned str(value).
Since str(value) returns a string in the NATIONAL format, the region information was lost.

Resolution

I fixed this issue by overriding to_python() in PhoneNumberField, ensuring that a PhoneNumber is returned.
This change forced me to move up the call to super().get_prep_value() because CharField's implementation calls self.to_python(), which now returns a PhoneNumber.
This allowed me to remove if isinstance(value, PhoneNumber) in get_prep_value() since value is now always a PhoneNumber.

Of course, I started with a unit test, which I tried to make as close as possible to the existing ones.
All tests are passing, but the mypy job is failing due to an internal error, which was already happening before my changes.

Please let me know if you have any questions.

Best Regards,
Benoit

@francoisfreitag francoisfreitag force-pushed the phonenumberfield-topython branch from 099c2d2 to 632b84b Compare August 7, 2025 12:02
Copy link
Collaborator

@francoisfreitag francoisfreitag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation and providing a test case, it makes sense to me 🌟

@francoisfreitag
Copy link
Collaborator

(mypy should be removed with #637)

When `PHONENUMBER_DEFAULT_FORMAT` is set to `NATIONAL`, you used to get a validation error after setting a `PhoneNumberField` to a phone number that is not in the default region.
This was because `PhoneNumberField` didn't override `to_python()`, so `CharField.to_python()` was called and returned `str(value)`.
Since `str(value)` returns a string in the `NATIONAL` format, the region information was lost.

I fixed this issue by overriding `to_python()` in  `PhoneNumberField`, ensuring that a `PhoneNumber` is returned.
This change forced me to move up the call to `super().get_prep_value()` because `CharField`'s implementation calls `self.to_python()`, which now returns a `PhoneNumber`.
This allowed me to remove `if isinstance(value, PhoneNumber)` in `get_prep_value()` since `value` is now always a `PhoneNumber`.
@francoisfreitag francoisfreitag force-pushed the phonenumberfield-topython branch from c3cde79 to d7d20dd Compare August 22, 2025 06:53
@francoisfreitag francoisfreitag merged commit 5841446 into stefanfoulis:main Aug 22, 2025
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants