How to include custom functions in django serializers?

Viewed 4417

I've been trying all sorts of method but still cant seem to get this task done even through asking here with my previous questions. The problem is, I am trying to convert my data that is entered by the user on django's admin page to json data using rest. But before converting the data to json, I have 2 custom functions that validates the email and phone number fields entered by the user that uses packages from PyPI and I need these functions to run through the entered text values on the admin page. I dont know where to put my 2 functions in my python files, whether in models.py or serializers.py, Ive actually tried both ways but cant seem to get it to work.

/* models.py */ 

import re
import phonenumbers
from django.db import models
from phonenumbers import carrier
from validate_email import validate_email


class razer(models.Model):
    emailplus = models.EmailField()
    country = models.CharField(max_length=2)
    phone_number = models.CharField(max_length=100)

    def clean_emailplus(self):
        email = self.cleaned_data.get("emailplus")
        if not validate_email(email, check_mx=True, verify=True):
            raise models.ValidationError("Invalid email")
        return email

    def clean_phone_number(self):
        phone_number = self.cleaned_data.get("phone_number")
        clean_number = re.sub("[^0-9&^+]", "", phone_number)
        # alpha_2 = self.cleaned_data.get("country")
        alpha_2 = self.cleaned_data.get("country")
        z = phonenumbers.parse(clean_number, "%s" % (alpha_2))
        if len(clean_number) > 15 or len(clean_number) < 3:
            raise forms.ValidationError(
                "Number cannot be more than 15 or less than 3")
        if not phonenumbers.is_valid_number(z):
            raise forms.ValidationError(
                "Number not correct format or non-existent")
        if carrier.name_for_number(z, "en") == '':
            raise forms.ValidationError("Please enter a mobile number")
        return phonenumbers.format_number(
            z, phonenumbers.PhoneNumberFormat.E164)

    def __str__(self):
        return self.emailplus

/* serializers.py */ 
import re
import phonenumbers
from rest_framework import serializers
from .models import razer
from phonenumbers import carrier
from validate_email import validate_email


class razerSerializer(serializers.ModelSerializer):

    class Meta:
        model = razer
        fields = ('emailplus', 'country', 'phone_number')

/* views.py */ 
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import razer
from .serializers import razerSerializer


class razerList(APIView):

    def get(self, request):
        razer1 = razer.objects.all()
        serializer = razerSerializer(razer1, many=True)
        return Response(serializer.data)

    def post(self):
        pass

Also if I put the phonenumber and email fields in my serializers.py as in phone_number = serializers.CharField(), and then put the 2 custom functions as well, do I have to register serializer as a model and what should my views.py be changed into as it is using models.py currently . Please tell me what changes should be made, as I need to validate the text values entered by the users on the admin page on the registered model or via another method where users can enter the text separately.

2 Answers

You could create a custom validator on your serialize for emailplus field.

    def clean_emailplus(value):
        email = value
        if not validate_email(email, check_mx=True, verify=True):
            raise serializers.ValidationError("Invalid email")

    class razerSerializer(serializers.ModelSerializer):
        emailplus = serializers.StringField(validators=[clean_emailplus])

        class Meta:
            model = razer
            fields = ('emailplus', 'country', 'phone_number')

If you are creating a Django rest framework application, you need to use the validate method in the serializer.

def validate(self, data):
        # clean the data
        return data
Related