EmailVerify LogoEmailVerify

Django

Email checker for Django. Python email verification in Django views and forms.

Integreer EmailVerify met Django applicaties met behulp van aangepaste validators, formuliervelden en middleware.

Installatie

pip install emailverify

Configuratie

Voeg toe aan uw Django instellingen:

# settings.py
EMAILVERIFY_API_KEY = os.environ.get('EMAILVERIFY_API_KEY')

# Optionele instellingen
EMAILVERIFY_TIMEOUT = 10  # seconden
EMAILVERIFY_BLOCK_DISPOSABLE = True
EMAILVERIFY_BLOCK_ROLE_BASED = False
EMAILVERIFY_CACHE_DURATION = 3600  # 1 uur

Aangepaste Validator

Maak een herbruikbare e-mail validator.

# validators.py
from django.core.exceptions import ValidationError
from django.conf import settings
from emailverify import Client
import logging

logger = logging.getLogger(__name__)

def validate_email_deliverable(email):
    """Valideer dat een e-mailadres afleverbaar is."""
    client = Client(api_key=settings.EMAILVERIFY_API_KEY)

    try:
        result = client.verify(email)

        if result.status == 'invalid':
            raise ValidationError(
                'Voer een geldig e-mailadres in.',
                code='invalid_email'
            )

        if getattr(settings, 'EMAILVERIFY_BLOCK_DISPOSABLE', True):
            if result.result.disposable:
                raise ValidationError(
                    'Wegwerp e-mailadressen zijn niet toegestaan.',
                    code='disposable_email'
                )

        if getattr(settings, 'EMAILVERIFY_BLOCK_ROLE_BASED', False):
            if result.result.role:
                raise ValidationError(
                    'Rolgebaseerde e-mailadressen zijn niet toegestaan.',
                    code='role_email'
                )

    except Exception as e:
        # Log fout maar blokkeer inzending niet
        logger.warning(f'E-mailverificatie mislukt voor {email}: {e}')


class EmailDeliverableValidator:
    """Class-gebaseerde validator met aanpasbare opties."""

    def __init__(self, block_disposable=True, block_role_based=False):
        self.block_disposable = block_disposable
        self.block_role_based = block_role_based
        self.client = Client(api_key=settings.EMAILVERIFY_API_KEY)

    def __call__(self, email):
        try:
            result = self.client.verify(email)

            if result.status == 'invalid':
                raise ValidationError(
                    'Voer een geldig e-mailadres in.',
                    code='invalid_email'
                )

            if self.block_disposable and result.result.disposable:
                raise ValidationError(
                    'Wegwerp e-mailadressen zijn niet toegestaan.',
                    code='disposable_email'
                )

            if self.block_role_based and result.result.role:
                raise ValidationError(
                    'Rolgebaseerde e-mailadressen zijn niet toegestaan.',
                    code='role_email'
                )

        except ValidationError:
            raise
        except Exception as e:
            logger.warning(f'E-mailverificatie mislukt: {e}')

    def __eq__(self, other):
        return (
            isinstance(other, EmailDeliverableValidator) and
            self.block_disposable == other.block_disposable and
            self.block_role_based == other.block_role_based
        )

Model Veld

Voeg verificatie toe aan modelvelden.

# models.py
from django.db import models
from .validators import validate_email_deliverable

class User(models.Model):
    email = models.EmailField(
        unique=True,
        validators=[validate_email_deliverable]
    )
    name = models.CharField(max_length=255)
    email_verification_status = models.CharField(
        max_length=20,
        blank=True,
        null=True
    )
    email_verification_score = models.FloatField(
        blank=True,
        null=True
    )
    email_verified_at = models.DateTimeField(
        blank=True,
        null=True
    )

    class Meta:
        db_table = 'users'

Formulier Integratie

Basis Formulier

# forms.py
from django import forms
from django.core.validators import EmailValidator
from .validators import EmailDeliverableValidator

class RegistrationForm(forms.Form):
    name = forms.CharField(max_length=255)
    email = forms.EmailField(
        validators=[
            EmailValidator(),
            EmailDeliverableValidator(
                block_disposable=True,
                block_role_based=False
            )
        ]
    )
    password = forms.CharField(widget=forms.PasswordInput)
    password_confirm = forms.CharField(widget=forms.PasswordInput)

    def clean(self):
        cleaned_data = super().clean()
        password = cleaned_data.get('password')
        password_confirm = cleaned_data.get('password_confirm')

        if password and password_confirm and password != password_confirm:
            raise forms.ValidationError('Wachtwoorden komen niet overeen.')

        return cleaned_data

Model Formulier

# forms.py
from django import forms
from .models import User
from .validators import validate_email_deliverable

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['name', 'email']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Voeg validator toe aan e-mailveld
        self.fields['email'].validators.append(validate_email_deliverable)

View Integratie

# views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from django.views import View
from emailverify import Client
from django.conf import settings
from .forms import RegistrationForm
from .models import User

class RegistrationView(View):
    template_name = 'registration/register.html'

    def get(self, request):
        form = RegistrationForm()
        return render(request, self.template_name, {'form': form})

    def post(self, request):
        form = RegistrationForm(request.POST)

        if form.is_valid():
            # Extra verificatie met volledig resultaat
            client = Client(api_key=settings.EMAILVERIFY_API_KEY)
            email = form.cleaned_data['email']

            try:
                result = client.verify(email)

                # Maak gebruiker met verificatiegegevens
                user = User.objects.create(
                    name=form.cleaned_data['name'],
                    email=email,
                    email_verification_status=result.status,
                    email_verification_score=result.score,
                )
                user.set_password(form.cleaned_data['password'])
                user.save()

                messages.success(request, 'Registratie succesvol!')
                return redirect('login')

            except Exception as e:
                messages.error(request, 'Registratie mislukt. Probeer het opnieuw.')

        return render(request, self.template_name, {'form': form})

Middleware

Verifieer e-mails in inkomende verzoeken.

# middleware.py
from django.http import JsonResponse
from django.conf import settings
from emailverify import Client
import logging
import json

logger = logging.getLogger(__name__)

class EmailVerificationMiddleware:
    """Middleware om e-mailadressen in POST verzoeken te verifieren."""

    def __init__(self, get_response):
        self.get_response = get_response
        self.client = Client(api_key=settings.EMAILVERIFY_API_KEY)
        self.protected_paths = getattr(
            settings,
            'EMAILVERIFY_PROTECTED_PATHS',
            ['/api/register/', '/api/subscribe/']
        )

    def __call__(self, request):
        if request.method == 'POST' and self._should_verify(request.path):
            email = self._extract_email(request)

            if email:
                try:
                    result = self.client.verify(email)

                    if result.status == 'invalid':
                        return JsonResponse(
                            {'error': 'Ongeldig e-mailadres'},
                            status=400
                        )

                    # Voeg verificatieresultaat toe aan verzoek
                    request.email_verification = result

                except Exception as e:
                    logger.warning(f'E-mailverificatie mislukt: {e}')

        return self.get_response(request)

    def _should_verify(self, path):
        return any(path.startswith(p) for p in self.protected_paths)

    def _extract_email(self, request):
        # Probeer JSON body
        if request.content_type == 'application/json':
            try:
                data = json.loads(request.body)
                return data.get('email')
            except json.JSONDecodeError:
                pass

        # Probeer POST data
        return request.POST.get('email')

Registreer Middleware

# settings.py
MIDDLEWARE = [
    # ... andere middleware
    'myapp.middleware.EmailVerificationMiddleware',
]

EMAILVERIFY_PROTECTED_PATHS = [
    '/api/register/',
    '/api/subscribe/',
    '/api/contact/',
]

Caching

Cache verificatieresultaten om API-aanroepen te verminderen.

# services.py
from django.core.cache import cache
from django.conf import settings
from emailverify import Client
import hashlib

class EmailVerificationService:
    def __init__(self):
        self.client = Client(api_key=settings.EMAILVERIFY_API_KEY)
        self.cache_duration = getattr(
            settings,
            'EMAILVERIFY_CACHE_DURATION',
            3600
        )

    def verify(self, email):
        cache_key = self._get_cache_key(email)
        cached = cache.get(cache_key)

        if cached:
            return cached

        result = self.client.verify(email)
        cache.set(cache_key, result, self.cache_duration)

        return result

    def is_valid(self, email):
        result = self.verify(email)
        return result.status == 'valid'

    def is_disposable(self, email):
        result = self.verify(email)
        return result.result.disposable

    def clear_cache(self, email):
        cache.delete(self._get_cache_key(email))

    def _get_cache_key(self, email):
        email_hash = hashlib.md5(email.lower().encode()).hexdigest()
        return f'email_verification:{email_hash}'


# Gebruik
verification_service = EmailVerificationService()

if verification_service.is_valid(email):
    # Verwerk geldige e-mail
    pass

Django REST Framework

Serializer Validatie

# serializers.py
from rest_framework import serializers
from django.conf import settings
from emailverify import Client

class RegistrationSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=255)
    email = serializers.EmailField()
    password = serializers.CharField(write_only=True)

    def validate_email(self, value):
        client = Client(api_key=settings.EMAILVERIFY_API_KEY)

        try:
            result = client.verify(value)

            if result.status == 'invalid':
                raise serializers.ValidationError(
                    'Voer een geldig e-mailadres in.'
                )

            if result.result.disposable:
                raise serializers.ValidationError(
                    'Wegwerp e-mails zijn niet toegestaan.'
                )

            # Sla resultaat op voor later gebruik
            self.context['email_verification'] = result

        except serializers.ValidationError:
            raise
        except Exception as e:
            # Log maar blokkeer niet
            pass

        return value

Aangepaste Toestemming

# permissions.py
from rest_framework.permissions import BasePermission
from django.conf import settings
from emailverify import Client

class ValidEmailPermission(BasePermission):
    """Sta alleen verzoeken met geldige e-mailadressen toe."""

    message = 'Een geldig e-mailadres is vereist.'

    def has_permission(self, request, view):
        email = request.data.get('email')

        if not email:
            return True  # Laat andere validators ontbrekende e-mail afhandelen

        client = Client(api_key=settings.EMAILVERIFY_API_KEY)

        try:
            result = client.verify(email)
            return result.status != 'invalid'
        except Exception:
            return True  # Toestaan bij API fouten

Management Commando

Bulk verificatie van gebruikers e-mails.

# management/commands/verify_emails.py
from django.core.management.base import BaseCommand
from django.conf import settings
from emailverify import Client
from myapp.models import User
import time

class Command(BaseCommand):
    help = 'Verifieer alle e-mailadressen van gebruikers'

    def add_arguments(self, parser):
        parser.add_argument(
            '--batch-size',
            type=int,
            default=100,
            help='Aantal e-mails per batch'
        )

    def handle(self, *args, **options):
        client = Client(api_key=settings.EMAILVERIFY_API_KEY)
        batch_size = options['batch_size']

        users = User.objects.filter(
            email_verification_status__isnull=True
        )

        total = users.count()
        self.stdout.write(f'Verifieren van {total} e-mails...')

        # Verzamel e-mails voor bulk verificatie
        emails = list(users.values_list('email', flat=True)[:10000])

        # Dien bulk taak in
        job = client.verify_bulk(emails)
        self.stdout.write(f'Taak ID: {job.job_id}')

        # Wacht op voltooiing
        while True:
            status = client.get_bulk_job_status(job.job_id)
            self.stdout.write(
                f'Voortgang: {status.progress_percent}%',
                ending='\r'
            )

            if status.status == 'completed':
                break

            time.sleep(5)

        self.stdout.write('')

        # Haal resultaten op en werk gebruikers bij
        results = client.get_bulk_job_results(job.job_id)

        for result in results.results:
            User.objects.filter(email=result.email).update(
                email_verification_status=result.status,
                email_verification_score=result.score,
            )

        self.stdout.write(self.style.SUCCESS('Verificatie voltooid!'))

        # Print samenvatting
        summary = {}
        for result in results.results:
            summary[result.status] = summary.get(result.status, 0) + 1

        for status, count in summary.items():
            self.stdout.write(f'  {status}: {count}')

Signalen

Reageer op model events.

# signals.py
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.conf import settings
from emailverify import Client
from .models import User
import logging

logger = logging.getLogger(__name__)

@receiver(pre_save, sender=User)
def verify_user_email(sender, instance, **kwargs):
    """Verifieer e-mail voor opslaan van gebruiker."""
    # Sla over als e-mail niet is gewijzigd
    if instance.pk:
        try:
            old_instance = User.objects.get(pk=instance.pk)
            if old_instance.email == instance.email:
                return
        except User.DoesNotExist:
            pass

    client = Client(api_key=settings.EMAILVERIFY_API_KEY)

    try:
        result = client.verify(instance.email)
        instance.email_verification_status = result.status
        instance.email_verification_score = result.score

    except Exception as e:
        logger.warning(f'E-mailverificatie mislukt: {e}')

Testen

# tests.py
from django.test import TestCase
from unittest.mock import patch, MagicMock
from .validators import validate_email_deliverable
from django.core.exceptions import ValidationError

class EmailValidationTest(TestCase):
    @patch('validators.Client')
    def test_valid_email_passes(self, mock_client):
        mock_result = MagicMock()
        mock_result.status = 'valid'
        mock_result.result.disposable = False
        mock_result.result.role = False

        mock_client.return_value.verify.return_value = mock_result

        # Mag geen fout geven
        validate_email_deliverable('valid@example.com')

    @patch('validators.Client')
    def test_invalid_email_fails(self, mock_client):
        mock_result = MagicMock()
        mock_result.status = 'invalid'

        mock_client.return_value.verify.return_value = mock_result

        with self.assertRaises(ValidationError):
            validate_email_deliverable('invalid@example.com')

    @patch('validators.Client')
    def test_disposable_email_blocked(self, mock_client):
        mock_result = MagicMock()
        mock_result.status = 'valid'
        mock_result.result.disposable = True

        mock_client.return_value.verify.return_value = mock_result

        with self.assertRaises(ValidationError):
            validate_email_deliverable('temp@mailinator.com')

Gerelateerde Bronnen

On this page