首页 > 解决方案 > 显示 django 注册表错误

问题描述

我想在用户尝试注册时显示注册错误,但他做错了一些事情,比如输入现有的电子邮件地址或两个密码不匹配,或者当 django 的默认密码验证器之一不被视为输入短密码时,并且能够使用引导警报设置每个错误的样式,正如我在模板中显示的那样

models.py 中的用户模型

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings

class User(AbstractBaseUser):
    email = models.EmailField(verbose_name="Email",max_length=250, unique=True)
    username = models.CharField(max_length=30, unique=True, null=True)
    date_joined = models.DateTimeField(verbose_name='Date joined', auto_now_add=True)
    last_login = models.DateTimeField(verbose_name='Last login', auto_now=True)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    full_name = models.CharField(verbose_name="Full name", max_length=150, null=True)
    profile_pic = models.ImageField(null=True, blank=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['full_name']

    objects = MyAccountManager()

    def __str__(self):
        return self.full_name

    # For checking permissions.
    def has_perm(self, perm, obj=None):
        return self.is_admin

    # For which users are able to view the app (everyone is)
    def has_module_perms(self, app_label):
        return True

在 views.py 中具有注册/注册表单的视图

def home(request):

    user = request.user

    # for rendring texts

    form = TextForm()

    if request.method == "POST":
        form = TextForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            author = User.objects.filter(email=user.email).first()
            obj.author = author
            form.save()
            form = TextForm()

    texts = Text.objects.all().order_by('-id')

    # for signing in

    if request.POST:
        signin_form = SigninForm(request.POST)
        if signin_form.is_valid():
            email = request.POST['email']
            password = request.POST['password']
            user = authenticate(email=email, password=password)
            if user:
                login(request, user)
            elif user is None:
                messages.error(request,'ُEmail or password is incorrect')
    else:
        signin_form = SigninForm()


    
    # for signing up

        signup_form = SignupForm()
    if request.method == 'POST':
        signup_form = SignupForm(request.POST)
        if signup_form.is_valid():
            User = signup_form.save()
            full_name = signup_form.cleaned_data.get('full_name')
            email = signup_form.cleaned_data.get('email')
            raw_password = signup_form.cleaned_data.get('password1')
            account = authenticate(email=email, password=raw_password)
            login(request, account)
        else:
            signup_form = SignupForm()
        

    context = {'signin_form':signin_form,'signup_form':signup_form,'form': form, 'texts': texts}

    return render(request, 'main/home.html', context)

我在 forms.py 中的注册表单

class SignupForm(UserCreationForm):
    password1 = forms.CharField(widget=forms.PasswordInput(
        attrs={'placeholder': 'Password', 'class': 'form-control mt-3'}))
    password2 = forms.CharField(widget=forms.PasswordInput(
        attrs={'placeholder': 'Confirm your password', 'class': 'form-control mt-3 mb-3', }))

    class Meta:
        model = User
        fields = ("full_name", "email", "password1", "password2")
        widgets = {
            'full_name': forms.TextInput(attrs={'placeholder': 'Full name', 'class': 'form-control mb-3', }),
            'email': forms.EmailInput(attrs={'placeholder': 'Email', 'class': 'form-control', }),
        }

在模板中

 <div id="signup" class="container tab-pane fade"><br>
                        <form action="" method="POST">
                            {% csrf_token %}

                            {{signup_form.full_name}}

                            {{signup_form.email}}

                            {{signup_form.password1}}

                            {{signup_form.password2}}


                            <button class="btn btn-success form-control" type="submit">Sign up</button>



                            {% if signup_form.errors %}
                            {% for field in signup_form %}
                            {% for error in field.errors %}
                            <div class="alert alert-danger alert-dismissible fade show"> {{ error}}

                                <button type="button" class="close" data-dismiss="alert">&times;</button>

                            </div>
                            {% endfor %}
                            {% endfor %}
                            {% endif %}
                        </form>

我尝试了 form.errors 而不是 signup_form.errors 它呈现了同一模板中另一个表单的错误

标签: pythondjangodjango-formsdjango-viewsdjango-templates

解决方案


一旦你调用form.is_valid()了表单的实例,如果有错误就变得非常重要,因为这些错误存在于那个实例上。因此,您需要将其传回给用户以显示错误。

我的意思的一个简单例子是;

    def register(request):
        form = CustomUserCreationForm()
            
        if request.method == "POST":
    
            form = CustomUserCreationForm(request.POST)
    
            if form.is_valid():
                user = form.save(commit=False)
    
                user.is_valid = False
                user.save()
                # Maybe redirect here
            else:
                messages.info(request, 'invalid registration details')
                
        return render(
            request, "users/register.html",
            {"form": form}
        )

这样,您就可以遍历模板中的错误。


    <form method="post" action="">
        {% csrf_token %}

        {% if form.non_field_errors %}
            {% for error in form.non_field_errors %}
                {{ error }}
            {% endfor %}
        {% endif %}

        {% for hidden in form.hidden_fields %}
            {{ hidden }}
        {% endfor %}

        {% for field in form %}
            {{ field }}
            {{ field.errors.as_ul }}
        {% endfor %}

        <button class="btn btn-primary" type="submit">Submit</button>
    </form>

像这样的更通用的模板也将对您有所帮助,因为您可以将它重用于任何表单,而不是像在您的示例中那样指定特定的表单和字段名称。

我要指出的另一件事是,您的观点有很多复杂性,例如对请求方法的大量检查。还有3种不同的形式。如果您在一个页面中有不同的表单,您可以命名提交按钮,以便您可以检查正在提交的表单。我在这里有一个答案来展示如何处理多个表单。

user.email没有检查用户是否经过身份验证或检查电子邮件是否存在,所以那里也有一个错误等待发生。

因此,为了简化您的视图,您可以执行以下操作(在命名表单按钮之后);


def home(request):
    user = request.user

    # for rendering texts
    text_form = TextForm()
    signin_form = SigninForm()
    signup_form = SignupForm()

    if request.method == "POST":
        if 'text_form' in request.POST:
            text_form = TextForm(request.POST)
            if text_form.is_valid() and request.user.is_authenticated:
                obj = text_form.save(commit=False)
                author = User.objects.filter(email=user.email).first()
                obj.author = author
                text_form.save()

        if 'signin_form' in request.POST:
            signin_form = SigninForm(request.POST)
            if signin_form.is_valid():
                email = request.POST['email']
                password = request.POST['password']
                user = authenticate(email=email, password=password)
                if user:
                    login(request, user)
                elif user is None:
                    messages.error(request, 'ُEmail or password is incorrect')

        if 'signup_form' in request.POST:
            signup_form = SignupForm(request.POST)
            if signup_form.is_valid():
                User = signup_form.save()
                full_name = signup_form.cleaned_data.get('full_name')
                email = signup_form.cleaned_data.get('email')
                raw_password = signup_form.cleaned_data.get('password1')
                account = authenticate(email=email, password=raw_password)
                login(request, account)

    texts = Text.objects.all().order_by('-id')

    context = {
        'signin_form': signin_form,
        'signup_form': signup_form,
        'text_form': text_form,
        'texts': texts
    }

    return render(request, 'main/home.html', context)


推荐阅读