django.db.utils.DataError: integer out of range
As promised, I will share all the major errors I encounter in my journey as a Junior Developer. Welcome to my series of Django Errors.
I am currently working on a project that requires account holders to accept some terms and conditions before they proceed with their transactions. This is supposed to be a one-time acceptance. By the way, I am running Django==4.1.1.
My model looks like this:
class Terms(models.Model):
SELECT_CHANNEL=(
('USSD': 'ussd'),
('ONLINE_BANKING':'online_banking'),
('MOBILE_BANKING':'mobile_banking'),
)
TERMS_STATUSES=(
('ACCEPTED':'accepted'),
('NOT_ACCEPTED':'not_accepted')
)
terms_status=models.CharField(max_length=25,
choices=TERMS_STATUSES,default=TERMS_STATUSES[0][0])
channel=models.CharField(max_length=25, null=False,default=SELECT_CHANNEL[0][0])
bvn= models.IntegerField(unique=True, null=True)
phone_number=PhoneNumberField(unique=True,null=True)
def __str__(self):
return f"<Customer {self.bvn} from {self.channel} channel has {self.terms_status}>"
My Serializer:
class AcceptTermsSerializer(serializers.ModelSerializer):
channel=serializers.CharField(required=True)
bvn= serializers.BigIntegerField(min_value=None)
phone_number=PhoneNumberField(required=False)
# terms_status=serializers.CharField(max_length=25)
class Meta:
model = Terms
fields = ['channel', 'bvn', 'phone_number' ]
As you can see i have my bvn fields in the models defined as IntegerField. It was working fine during the development cycle where I was using SQLite for the DB backend. However, as soon as I rolled off to Postgres, it threw error :
django.db.utils.DataError: integer out of range
Apparently, IntegerField can only take a maximum of 9 digits because when i tried to reduce the number of characters for bvn it worked.
As the Junior Dev that I am, I started googling and i found out there is django field for big numbers and its called BigIntegerFields. I implemented this immediately and did a migration but to my surprise, it threw another error:
bvn= serializers.BigIntegerField(min_value=None)
AttributeError: module 'rest_framework.serializers' has no attribute 'BigIntegerField'. Did you mean: 'IntegerField'?
I went back to consult the oracle (Google+ Stack Overflow) and i found that django rest_framework doesn’t take BigIntegerField in its serializer.
The documentation isn’t as clear about BigIntegerFields from models, but the source code shows that IntegerField is again what you have to use in the serializer.
Corrected Model:
terms_status=models.CharField(max_length=25, choices=TERMS_STATUSES,default=TERMS_STATUSES[0][0])
channel=models.CharField(max_length=25, null=False,default=SELECT_CHANNEL[0][0])
bvn= models.BigIntegerField(unique=True, null=True)
phone_number=PhoneNumberField(unique=True,null=True)
def __str__(self):
return f"<Customer {self.bvn} from {self.channel} channel has {self.terms_status}>"
Corrected Serializer:
class AcceptTermsSerializer(serializers.ModelSerializer):
channel=serializers.CharField(required=True)
bvn= serializers.IntegerField(min_value=None)
phone_number=PhoneNumberField(required=False)
# terms_status=serializers.CharField(max_length=25)
class Meta:
model = Terms
fields = ['channel', 'bvn', 'phone_number' ]
class TermsStatusUpdateSerializer(serializers.ModelSerializer):
terms_status=serializers.CharField(default='NOT_ACCEPTED')
class Meta:
model = Terms
fields = ['terms_status']
I hope you find this useful and check for more error solutions.