Django register mit unique email

Django, Flask, Bottle, WSGI, CGI…
Antworten
snowball
User
Beiträge: 3
Registriert: Mittwoch 1. August 2018, 20:02

Mittwoch 1. August 2018, 20:16

Hallo,

ich habe mir dieses Projekt runtergeladen um mit Django etwas zu experimentieren.

Ich versuche gerade bei der Registrierung das Email Feld einzigartig zu machen, also das jede Email nur einmal exisitert.

Nur komme ich da nicht weiter.

views.py

Code: Alles auswählen

def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            for u in form:
                if u.email == form.cleaned_data.get("email"):
                    context = {
                        'form': form,
                        'error_message': 'You already registered this email',
                    }
                    return render(request, 'account/register.html', context)
            user = form.save()
            user.refresh_from_db()  # load the profile instance created by the signal
            user.profile.birth_date = form.cleaned_data.get('birth_date')
            user.save()
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            return render(request, 'account/index.html')
            #return redirect('index')
    else:
        form = SignUpForm()
    return render(request, 'account/register.html', {'form': form})
forms.py

Code: Alles auswählen

class SignUpForm(UserCreationForm):

    class Meta:
        model = User
        fields = ('email', 'password1', 'password2', )

Ich bekomme allerdings diese Fehlermeldung:
Exception Value: 'BoundField' object has no attribute 'email'

\views.py in signup
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
for user in form:
if user.email == form.cleaned_data.get("email"): ...
context = {
'form': form,
'error_message': 'You already registered this email',
}
return render(request, 'account/register.html', context)

▼ Local vars
Variable Value
form
<SignUpForm bound=True, valid=True, fields=(email;password1;password2)>
request
<WSGIRequest: POST '/profile/signup/'>
user
<django.forms.boundfield.BoundField object at 0x0430BE50>
Nur verstehe ich gerade nicht warum...

Ach ja, ich verwende:
Django Version: 2.0.7
Python Version: 3.7.0
Sirius3
User
Beiträge: 8255
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 1. August 2018, 20:30

Das nächste ml solltest Du den Code posten, der den Fehler produziert, und nicht einen anderen.
Ein Form-Feld hat halt kein Attribut »email«, sondern nur einen Namen und einen oder mehrere Werte. Du hast auch eine falsche Vorstellung, was denn eine Schleife über eine Form ergibt.

Wenn Du die email-Addresse eindeutig sein soll, dann definier sie in der Datenbank als unique. Dann gibt es automatisch eine Fehlermeldung, wenn Du versuchst, eine weitere gleiche Email einzutragen.
snowball
User
Beiträge: 3
Registriert: Mittwoch 1. August 2018, 20:02

Mittwoch 1. August 2018, 20:39

Das ist genau der Code, der den Fehler verursacht. Und in der user Tabelle, da kann ich keine Änderungen vornehmen.
Benutzeravatar
__blackjack__
User
Beiträge: 1040
Registriert: Samstag 2. Juni 2018, 10:21

Mittwoch 1. August 2018, 20:48

@snowball: Das ist nicht genau der Code. Beim gezeigten Quelltext heisst es beispielsweise `u`, beim Code im Traceback aber `user`. Und warum kannst Du an der Tabelle keine Änderung vornehmen? Also insbesondere *die* Änderung die das Problem löst.
“Capitalism is the astounding belief that the most wickedest of men will do the most wickedest of things for the greatest good of everyone.” – John Maynard Keynes
snowball
User
Beiträge: 3
Registriert: Mittwoch 1. August 2018, 20:02

Mittwoch 1. August 2018, 21:15

Das ist die komplette views.py

Code: Alles auswählen

from django.contrib.auth import authenticate, login
from django.contrib.auth import logout
from django.urls import reverse
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.forms import UserChangeForm, PasswordChangeForm
from django.db.models import Q
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from .forms import SignUpForm
from account.forms import EditProfileForm, EditUserForm
from django.contrib.auth import update_session_auth_hash


def index(request):
    if not request.user.is_authenticated:
        return render(request, 'account/login.html')
    else:
        return render(request, 'account/index.html')


def logout_user(request):
    logout(request)
    form = SignUpForm(request.POST or None)
    context = {
        "form": form,
    }
    return render(request, 'account/login.html', context)


def get_user(email):
    try:
        return User.objects.get(email=email.lower())
    except User.DoesNotExist:
        return None


def login_user(request):
    if request.method == "POST":
        email = request.POST['username']
        username = get_user(email)
        #username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                return render(request, 'account/index.html')
            else:
                return render(request, 'account/login.html', {'error_message': 'Your account has been disabled'})
        else:
            return render(request, 'account/login.html', {'error_message': 'Invalid login'})
    return render(request, 'account/login.html')


def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            for u in form:
                if u.email == form.cleaned_data.get("email"):
                    context = {
                        'form': form,
                        'error_message': 'You already registered this email',
                    }
                    return render(request, 'account/register.html', context)
            user = form.save()
            user.refresh_from_db()  # load the profile instance created by the signal
            user.profile.birth_date = form.cleaned_data.get('birth_date')
            user.save()
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request, user)
            return render(request, 'account/index.html')
            #return redirect('index')
    else:
        form = SignUpForm()
    return render(request, 'account/register.html', {'form': form})


def edit_profile(request):
    if request.method == 'POST':
        user_form = EditUserForm(request.POST, instance=request.user)
        profile_form = EditProfileForm(request.POST, instance=request.user.profile)

        if all([user_form.is_valid(), profile_form.is_valid()]):
            user_form.save()
            profile_form.save()
            return render(request, 'account/index.html')
    else:
        user_form = EditUserForm(instance=request.user)
        profile_form = EditProfileForm(instance=request.user.profile)
        args = {'user_form': user_form, 'profile_form': profile_form}
        return render(request, 'account/edit_profile.html', args)


def change_password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(data=request.POST, user=request.user)
        update_session_auth_hash(request, form.user)
        if form.is_valid():
            form.save()

            return render(request, 'account/index.html')
        else:
            return redirect(reverse('accounts:change_password'))
    else:
        form = PasswordChangeForm(user=request.user)
        args = {'form': form, }
        return render(request, 'account/password_change.html', args)
models.py

Code: Alles auswählen

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    birth_date = models.DateField(null=True, blank=True)
    street = models.CharField(max_length=30, null=True, blank=True)
    house_number = models.CharField(max_length=30, null=True, blank=True)
    zip_code = models.CharField(max_length=30, null=True, blank=True)
    country = models.CharField(max_length=30, null=True, blank=True)
    location = models.CharField(max_length=30, null=True, blank=True)


@receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()
forms.py

Code: Alles auswählen

from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.models import User


from account.models import Profile

class SignUpForm(UserCreationForm):

    class Meta:
        model = User
        fields = ('email', 'password1', 'password2', )


class EditUserForm(forms.ModelForm):
    template_name ='/something/else'

    class Meta:
        model = User
        fields = (
            'email',
            'first_name',
            'last_name'
        )


class EditProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = (
           'birth_date',
           'street',
           'house_number',
           'zip_code',
           'country',
           'location',
            )

    birth_date = forms.DateField(
        widget=forms.DateInput(format='%d/%m/%Y'),
        input_formats=('%d/%m/%Y',)
        )
auth.user ist nicht mit in der models.py konfiguriert, das wird vom Django selber übernommen. Deswegen kann ich das nicht direkt ändern. Oder sprechen wir gerade aneinander vorbei?
Sirius3
User
Beiträge: 8255
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 1. August 2018, 21:48

Wie mal selbst definierte User macht, steht hier beschrieben.

Der einzige konsistente Weg, die Email-Adresse als eindeutig zu definieren, geht über die Datenbank.
Antworten