Skip to content
Starten Sie mit 100 kostenlosen Verifizierungs-Credits
Qualisend
Alle Artikel
Engineering / 11. Juni 2026

So validieren Sie eine E-Mail-Adresse in Django

7 minutes read

Qualisend team
Code-Fenster mit dem Titel validators.py, das drei sich verengende Django-Validierungsschichten zeigt – validate_email, ein MX-Resolve und ein POST an die Verify-API –, das mit einem grünen Deliverable-Badge endet.

Um eine E-Mail-Adresse in Django zu validieren, führen Sie drei Prüfungen aus, nicht eine – und das Framework liefert nur die erste mit. Djangos Validatoren bestätigen, dass eine Adresse korrekt geformt ist; sie fragen niemals, ob ihre Domain Mails empfangen kann oder ob das Postfach existiert. Echte Validierung ist geschichtet: erst die Syntax, dann ein DNS-Lookup, dann eine SMTP-Postfachprüfung. Diese Anleitung baut jede Schicht als Django-Validator auf, den Sie in ein Formular oder einen Serializer des Django REST Framework einsetzen können, und zeigt, wo eine Verifizierungs-API übernimmt. Sie knüpft dort an, wo die Python-Anleitung aufhört, sodass die dortige Argumentation zu DNS und SMTP unverändert übertragbar ist.

Die kurze Antwort#

Verwenden Sie validate_email (oder ein beliebiges EmailField) für die Syntax, dnspython für das MX-Lookup und eine Verifizierungs-API für die SMTP-Postfachprüfung – verdrahtet als drei Validatoren, den günstigsten zuerst, mit Abbruch, sobald einer entscheidend ist. Öffnen Sie keine SMTP-Verbindungen aus Ihrem Django-Prozess, um Postfächer zu prüfen: Der ausgehende Port 25 ist auf den meisten Hosts blockiert, und die Antwort hängt von der Reputation der Sende-IP und von Greylisting ab, das Sie nicht nachbauen wollen. Jede Schicht schließt Adressen günstiger aus als die vorherige; nur die API kann eine Adresse einschließen. Falls Ihnen die Pipeline neu ist, klärt was E-Mail-Verifizierung ist zuerst die Begriffe.

Schicht 1: Formatvalidierung mit Djangos Validatoren#

Schicht eins beherrscht Django bereits. django.core.validators.validate_email ist eine EmailValidator-Instanz, die bei einer fehlerhaften Adresse ValidationError auslöst und bei einer gültigen None zurückgibt:

from django.core.validators import validate_email
from django.core.exceptions import ValidationError

def is_valid_syntax(email: str) -> bool:
    try:
        validate_email(email)
        return True
    except ValidationError:
        return False

Von Hand rufen Sie es selten auf. Jedes forms.EmailField, models.EmailField und DRF-serializers.EmailField hängt EmailValidator automatisch an, sodass Ihnen bereits die Deklaration eines Feldes die Syntaxvalidierung kostenlos liefert:

from django import forms

class SignupForm(forms.Form):
    email = forms.EmailField()  # EmailValidator runs during clean()

Machen Sie sich genau klar, was Ihnen das bringt. EmailValidator prüft die Form anhand einer aus dem RFC abgeleiteten Grammatik – es löst niemals DNS auf, öffnet niemals einen Socket und hat keine Ahnung, ob example.com existiert. definitely-fake@gmail.com besteht. info@company-that-folded.com besteht. typo@gmial.com besteht. Alle drei sind nicht zustellbar, und kein Validator, der nur die Zeichenkette liest, wird Ihnen das jemals sagen – aus demselben Grund, aus dem Regex-E-Mail-Validierung scheitert: Syntax und Zustellbarkeit sind unterschiedliche Fragen. Die eine ist eine Tatsache über die Zeichenkette; die andere eine Tatsache über das Internet.

Schicht 2: Nimmt die Domain Mails an?#

Dies ist die erste Schicht, die Django Ihnen nicht liefert, und sie lässt sich günstig ergänzen. Eine Domain ohne MX-Records kann für niemanden Mails annehmen, sodass ein einziges DNS-Lookup tote Domains, falsch geschriebene Firmennamen und erfundene TLDs aussortiert. Django hat keinen eingebauten MX-Resolver, greifen Sie also zu dnspython und verpacken Sie es in eine schlichte Funktion:

import dns.resolver  # pip install dnspython

def has_mail_route(domain: str) -> bool:
    try:
        return len(dns.resolver.resolve(domain, "MX")) > 0
    except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.NoNameservers):
        return False

Ein Django-Validator ist einfach eine aufrufbare Funktion, die bei ungültiger Eingabe ValidationError auslöst; machen Sie die Prüfung also zu einer solchen, und sie fügt sich direkt in die validators-Liste eines beliebigen Feldes ein:

from django.core.exceptions import ValidationError

def validate_deliverable_domain(email: str) -> None:
    domain = email.rsplit("@", 1)[-1]
    if not has_mail_route(domain):
        raise ValidationError("This domain can't receive email.")
validate_deliverable_domain("jane@gmail.com")               # passes
validate_deliverable_domain("jane@company-that-folded.com") # raises ValidationError

Wenn Sie Domains berücksichtigen möchten, die Mails über einen A-Record ohne MX annehmen, weichen Sie bei leerem MX-Satz auf das Auflösen von A/AAAA aus – aber eine MX-Prüfung deckt die überwiegende Mehrheit der echten Adressen ab.

Schicht 3: Existiert das Postfach tatsächlich?#

Schicht eins und zwei können eine Adresse nur ausschließen. Eine Domain kann perfekte MX-Records veröffentlichen und trotzdem kein Postfach unter der Adresse haben, die Ihnen vorliegt – noreply-9f2x@gmail.com hat gültige Syntax auf einer aktiven Mail-Route und ist dennoch ein Postfach, das nie angelegt wurde. Ein bestimmtes Postfach zu bestätigen bedeutet die SMTP-Zustellungskonversation: sich mit dem Mail-Host verbinden, RCPT TO absetzen, die Antwort lesen und die Verbindung trennen, bevor irgendetwas gesendet wird.

Im Prinzip könnten Sie das aus Django heraus mit smtplib skripten. In der Praxis sollten Sie es nicht von Ihrem Anwendungsserver aus ausführen: Die meisten Cloud-Hosts blockieren den ausgehenden Port 25, die Antwort hängt von der Reputation der IP ab, von der aus Sie sich verbinden, und empfangende Server greylisten unbekannte Absender und drosseln deren Rate – sodass eine Prüfung, die im lokalen Test funktioniert, in der Produktion stillschweigend versagt oder Sie auf eine Blockliste bringt. Wie E-Mail-Verifizierung funktioniert geht die gesamte Pipeline durch, samt Catch-all-Domains. Dies ist die Schicht, die es sich zu delegieren lohnt.

Qualisends Verify-Endpunkt führt die gesamte Pipeline aus – Syntax, DNS und die SMTP-Postfachprüfung – von reputationsverwalteter Infrastruktur aus und liefert ein Urteil. Rufen Sie ihn aus einem Validator heraus mit requests auf und lesen Sie Ihren Schlüssel aus der Umgebung:

import os
import requests  # pip install requests

QUALISEND_VERIFY_URL = "https://api.qualisend.com/v1/verify"

def verify(email: str) -> dict:
    res = requests.post(
        QUALISEND_VERIFY_URL,
        headers={"Authorization": f"Bearer {os.environ['QUALISEND_API_KEY']}"},
        json={"email": email},
        timeout=10,
    )
    res.raise_for_status()
    return res.json()["result"]  # {"status", "score", "reason", "sub_flags"}

Die Antwort ist ein { "result": { ... } }-Umschlag. Lesen Sie result["status"]deliverable, risky, undeliverable oder unknown – zusammen mit einem score, einem reason und sub_flags für Merkmale wie Rollen- oder Wegwerfadressen. Sehen Sie in der API-Referenz die genauen Feldformen nach; hier benötigen Sie nur den Status, um bei einer nicht zustellbaren Adresse eine Ausnahme auszulösen:

def validate_mailbox(email: str) -> None:
    if verify(email)["status"] == "undeliverable":
        raise ValidationError("We couldn't confirm a mailbox at this address.")

Sie könnten auch bei risky eine Ausnahme auslösen oder den score speichern und die Adresse durchlassen – das ist eine Frage der Richtlinie. undeliverable abzulehnen ist die sichere Standardeinstellung; die Anleitung zur serverlosen Registrierung behandelt, wie streng Sie am Erfassungspunkt sein sollten.

Die Schichten zusammenfügen, um eine E-Mail-Adresse in Django zu validieren#

Der idiomatische Ort, um die drei Schichten in einem Formular zusammenzusetzen, ist eine clean_<field>-Methode. Django ruft clean_email erst auf, nachdem der feldeigene EmailValidator bestanden hat, sodass die Syntax bereits erledigt ist; Sie fügen die Domain- und Postfachprüfungen der Reihe nach hinzu, wobei jede früh eine Ausnahme auslöst:

from django import forms

class SignupForm(forms.Form):
    email = forms.EmailField()  # layer 1 for free

    def clean_email(self):
        email = self.cleaned_data["email"]  # syntax already passed
        validate_deliverable_domain(email)  # layer 2 — cheap, local
        validate_mailbox(email)             # layer 3 — the API round-trip
        return email

Diese Reihenfolge ist der ganze Trick: Der EmailValidator des Feldes bricht bei Müll ab, bevor Ihr Code läuft, die lokale DNS-Prüfung schließt tote Domains kostenlos aus, und die API wird nur für Adressen aufgerufen, die beide bestanden haben. Validierung in falscher Reihenfolge – oder das Überspringen der günstigen Schichten – verbraucht bei jedem Tippfehler ein Guthaben.

Eine Sache sollten Sie vorab entscheiden: was passiert, wenn der API-Aufruf selbst fehlschlägt. Ein Netzwerk-Timeout oder eine requests-Ausnahme innerhalb von clean_email sollte einem echten Kunden keinen Validierungsfehler bescheren, den er nicht beheben kann. Fangen Sie den Fehler der Anfrage getrennt von ValidationError ab und behandeln Sie einen nicht erreichbaren Dienst als unknown statt als undeliverable – lassen Sie die Registrierung durch und verifizieren Sie die Adresse später erneut, anstatt die Registrierung an einem vorübergehenden Ausfall scheitern zu lassen. Die Syntax- und MX-Schichten liefen bereits lokal, sodass Sie nur die Schicht abmildern, die vom Netzwerk abhängt.

Da beide eigenen Validatoren Djangos ValidationError auslösen, lassen sich genau dieselben zwei Funktionen unverändert in einen Serializer des Django REST Framework einsetzen. Der validate_<field>-Hook von DRF fängt diese Ausnahme ab und verwandelt sie in ein sauberes 400:

from rest_framework import serializers

class SignupSerializer(serializers.Serializer):
    email = serializers.EmailField()  # layer 1 for free

    def validate_email(self, value):
        validate_deliverable_domain(value)  # layer 2
        validate_mailbox(value)             # layer 3
        return value

Dies ist dieselbe Drei-Schichten-Form, die Sie in der Node.js- und der Python-Version dieser Anleitung finden – die Schichtung, nicht das Framework, ist es, was Validierung funktionieren lässt. Wenn Sie auswählen, welcher Verifizierungsdienst Schicht drei unterstützt, stellt der API-Vergleich die Optionen gegenüber.

Häufig gestellte Fragen#

Reicht Djangos EmailValidator aus, um eine E-Mail-Adresse zu validieren?#

Für die Syntax ja – validate_email (und jedes EmailField, das darauf zurückgreift) ist die richtige Prüfung auf Schicht eins und besser als eine selbst gebaute Regex. Aber es validiert die Form, nicht die Zustellbarkeit: Es löst niemals DNS auf und kontaktiert keinen Mailserver, sodass ein Bestehen nur bedeutet "sieht aus wie eine E-Mail", nicht "wird zugestellt". Kombinieren Sie es mit einem MX-Lookup und einer SMTP-Postfachprüfung, bevor Sie der Adresse vertrauen.

Wie schreibe ich einen eigenen E-Mail-Validator in Django?#

Ein Validator ist eine beliebige aufrufbare Funktion, die den Wert entgegennimmt und im Fehlerfall django.core.exceptions.ValidationError auslöst. Definieren Sie eine Funktion wie validate_deliverable_domain(email), die bei einem Problem eine Ausnahme auslöst und andernfalls None zurückgibt, und übergeben Sie sie dann in der validators=[...]-Liste des Feldes oder rufen Sie sie aus der clean_email-Methode eines Formulars auf. Dieselbe aufrufbare Funktion funktioniert im validate_email-Hook eines DRF-Serializers, weil DRF Djangos ValidationError ebenfalls abfängt.

Kann ich aus Django heraus ohne API prüfen, ob ein Postfach existiert?#

Teilweise. dnspython bestätigt, dass die Domain Mails annimmt, was tote Domains kostenlos ausschließt und nichts weiter als eine kleine Abhängigkeit erfordert. Das Postfach zu bestätigen bedeutet eine SMTP-Konversation, die Sie mit smtplib versuchen können, aber nicht von Ihrem App-Server aus ausführen sollten – Port 25 ist weitverbreitet blockiert und das Ergebnis hängt von der Reputation Ihrer IP ab. Genau dafür ist ein Verifizierungsdienst da.

Sollte ich diese Prüfungen bei der Registrierung oder beim Bereinigen einer Liste ausführen?#

Beides, in unterschiedlicher Tiefe. Führen Sie die Syntax- und MX-Schichten synchron in clean_email aus – sie sind schnell genug, um die Anfrage zu blockieren und sofortiges Feedback zu geben – und reagieren Sie dort auch auf das Urteil der API. Behalten Sie die aufwendigere Batch-Verifizierung für die Listenbereinigung und Back-Office-Arbeit vor, wo Latenz keine Rolle spielt und Sie Adressen in großen Mengen verarbeiten können.


Bereit, die SMTP-Schicht hinzuzufügen? Werfen Sie eine syntaktisch perfekte Adresse in den kostenlosen E-Mail-Checker und beobachten Sie, wie eine vom EmailField genehmigte Zeichenkette als undeliverable zurückkommt, und verdrahten Sie dann dasselbe Urteil mit der API-Referenz in Ihre Formulare – Copy-Paste-Beispiele inklusive.

Your reputation, protected.

Clean your first list in minutes. 100 free credits, no card required.

Get started