stefanfoulis / django-phonenumber-field

A django model and form field for normalised phone numbers using python-phonenumbers
MIT License
1.48k stars 318 forks source link

Converting existing `CharFields` to `PhoneNumberField` with intact lookup #540

Closed lmbak closed 9 months ago

lmbak commented 1 year ago

When converting from:

class MyModel(Model):
     phone = CharField()

to

class MyModel(Model):
     phone = PhoneNumberField()

The old data is not lost. However, a lookup like:

my_result = MyModel.objects.filter(phone=PhoneNumber.from_string('+31629322282'))

does not yield any result; after re-saving all entries by doing:

for m in MyModel.objects.all():
    m.save()

The lookup does work. My guess is that when migrating from a Charfield to a PhoneNumberField some format conversion is not done. It would make sense that an AlterField operation in the migrations would convert the old values to the new values via PhoneNumber.from_string().

It is possible for the programmer to do this themselves through a custom migration of course.

Should this functionality be automatic?

francoisfreitag commented 1 year ago

Could it be the phone numbers in your DB were in a different format from PHONENUMBER_DB_FORMAT (default is E164)?

e.g.:

  1. with the CharField : 06 29322282 (national format)
  2. with the PhoneNumberField (before migrating the existing numbers) 06 29322282
  3. with the PhoneNumberField (after migrating the existing numbers) +31629322282

The lookup resolves to the value "+31629322282", which would explain why the lookup in case 2. was not successful.


Should this functionality be automatic?

On the happy path, it would be great. On the error path, it raises questions. What if a char entry is not a valid phone number? Also, I don’t see an option to hook a RunPython operation after an AlterField. If it’s not supported by Django, I doubt this project should go out of its way to implement it. The migration may also be quite slow on large databases, which could cause issues for some users (although they could probably fake the migration, it’s a bit of a bad surprise).

Maybe the documentation of the model field could mention the need to convert the data in the database when changing from a charfield to a phonenumber field?

mschoettle commented 1 year ago

I was wondering about something similar. Sorry for hijacking this issue, it's more of a question:

Let's assume we start using PhoneNumberField with leaving the default DB format as E164. Later, we want to support phone extensions and switch the format to INTERNATIONAL.

Am I correct to assume that I need to migrate all existing phone numbers to the new format in the DB?

francoisfreitag commented 1 year ago

Not necessarily. The code interprets the value from db using the custom to_python function defined by the project, which eventually calls PhoneNumber.from_string() without a format specification. So values stored as E164 will still be read correctly. Upon saving, the string representation of the value would change to use PHONENUMBER_DB_FORMAT, so entries in your database would be converted when you’re saving them, and new entries would use the INTERNATIONAL format. https://github.com/stefanfoulis/django-phonenumber-field/blob/a544964046319773f89f6444a8a5eb5837ad60c7/phonenumber_field/modelfields.py#L81-L106

francoisfreitag commented 9 months ago

Closing for inactivity. The path forward is unclear, and it looks like the original question has been answered.