Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use django-phonenumber_field in forms.py?

Tags:

django

I was trying to take phone number from user as part of his profile updating. I recently found out from stackoverflow that there's a library django-phonenumber_field with which I can easily take input the phone number. So I used it in the model.py like this

phone = PhoneNumberField(blank=True).

As it is mentioned in the django-phonenumber_field github repository here

that

As with CharField's, it is discouraged to use null=True.

So I didn't use that too. Then I tried to use that phone field in forms.py. Initially I was using this before came to know about phone field:

phone = forms.IntegerField(widget=forms.TextInput(attrs={'class': 'form-control'}), required=True)

When I am changing it to phone = PhoneNumberField()

and I'm migrating, it raised field error. . I coudln't find any forms.PhoneNumberField(). So when I'm keeping the field to be the Integerfield and running the server, I tried to get the input from user I get this error:

NOT NULL constraint failed: auth_profile.phone

Then I changed phone = PhoneNumberField(blank=True) to phone = PhoneNumberField(null=True, blank=True). which is discouraged. After that, though I didn't get any error but it doesn't matter what user type in the phone-field it always sets null in the database. Probably because I used Integerfield I kept in the forms.py mentioned above. Or I don't know the reason.

How can I add the PhoneNumberField() in the form or any mechanism so that in the database, user given value will be saved?

Edit As @Sam Bobel told me to post the models.py in details, here it is:

from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.utils.encoding import python_2_unicode_compatible
from django.dispatch import receiver
from phonenumber_field.modelfields import PhoneNumberField

@python_2_unicode_compatible
class Profile(models.Model):
    user = models.OneToOneField(User)
    # location = models.CharField(max_length=50, null=True, blank=True)
    # url = models.CharField(max_length=50, null=True, blank=True)
    # job_title = models.CharField(max_length=50, null=True, blank=True)
    user_sex = (('MALE', 'Male'), ('FEMALE', 'Female'))
    sex = models.CharField(max_length=6, default='Male', choices=user_sex)
    address = models.CharField(max_length=250, null=True, blank=True)
    city = models.CharField(max_length=250, null=True, blank=True)
    state = models.CharField(max_length=250, null=True, blank=True)
    country = models.CharField(max_length=250, null=True, blank=True)
    phone = PhoneNumberField(null=True)
    zip = models.IntegerField(null=True, blank=True)
    about = models.CharField(max_length=250, null=True, blank=True)
    email_confirmed = models.BooleanField(default=False)
    account_type = models.IntegerField(default=-1)

    class Meta:
        db_table = 'auth_profile'

    def __str__(self):
        return self.user.username

Now if I run migrations, I get

You are trying to change the nullable field 'phone' on profile to non-nullable without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)
 3) Quit, and let me add a default in models.py
Select an option: 

**forms.py**:

class ContactForm(forms.ModelForm):

    address = forms.CharField(
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
        max_length=300,
        required=True)
    city = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        max_length=30,
        required=True)
    state = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        max_length=30,
        required=True)
    country = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        max_length=30,
        required=True)
    phone = forms.IntegerField(widget=forms.TextInput(attrs={'class': 'form-control'}),
        required=True)
    zip = forms.IntegerField(widget=forms.TextInput(attrs={'class': 'form-control'}),
        required=True)

    class Meta:
        model = User
        fields = ['address', 'city', 'state', 'country', 'phone', 'zip']
like image 516
sphoenix Avatar asked Mar 08 '23 19:03

sphoenix


1 Answers

Here is how I am using phonenumber field in my project and till now it was working without any problems. Also I didn't have any troubles with migrations.

Inside model:

from phonenumber_field.modelfields import PhoneNumberField

phonenumber = PhoneNumberField(blank=True)

Inside form:

from phonenumber_field.formfields import PhoneNumberField

class ExampleForm(forms.ModelForm):

    phonenumber = PhoneNumberField(widget=forms.TextInput(attrs={'placeholder': _('Phone')}), 

                       label=_("Phone number"), required=False)
like image 77
Alexander Tyapkov Avatar answered Mar 15 '23 13:03

Alexander Tyapkov