如何在我自己的视图中使用 LoginView 并在 HTML 模板中显示?

how can I use LoginView in my own view and show in HTML templates?

我想使用现成的 Django LoginView,但同时我必须使用自己的视图在同一个 HTML 模板中进行注册。如果在 urls.py 文件中,我将连接 2 个视图,而不是先连接。所以我的问题是如何在我自己的视图中使用 LoginView 并在 jinja 中使用 2 种形式? 这是我的 views.py 文件和 html ;)

def index(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        formlog = auth_views.LoginView.as_view(template_name='main/index.html')

        if 'signup' in request.POST:
            if form.is_valid():
                form.supervalid()
                form.save()
                username = form.cleaned_data.get('username')
                messages.success(request, f'Dear {username} you have been created a new accound!')
                return redirect('main')
        elif 'login' in request.POST:
            if formlog.is_valid():
                formlog.save()
                username = form.cleaned_data.get('username')
                messages.success(request, f'Your account has been created! You are now able to log in')
                return redirect('main')
    else:
        form = UserRegisterForm()
        formlog = auth_views.LoginView.as_view(template_name='main/index.html')
    return render(request, 'main/index.html', {'form': form, 'formlog': formlog})
# this code is not working , but not returning any errors

HTML

{% if not user.is_authenticated %}
    <!-- Login -->
    <div class="container">
        <div class="log-1">
            <div class="log-0">
                <p class="logtitle">BareTalk</p>
                <form method="POST" name="login">
                    {% csrf_token %}
                    {{ formlog|crispy }}
                    <button class="log-button first" type="submit">Login</button>
                </form>
                <button class="log-button second"
                     onclick="modalwindowops.open();" id="signup">Sign Up</button>
            </div>
        </div>
    </div>

    <!-- Signup  -->
    <div class="modal-overlay">
        <div class="modal-window">
            <span class="close-modal" onclick="modalwindowops.close();">&times;</span>
            <form method="POST" name="signup">
                <p>Sign Up</p>
                {% csrf_token %}
                {{ form|crispy }}

                <button type="submit">Sign Up</button>
            </form>
        </div>
    </div>
{% else %}
    <h1>Welcome back Amigo!</h1>
{% endif %}

if 'signup' in request.POST:elif 'login' in request.POST: 都不会在您的 index() 视图中触发,因为您的 HTML 表单实际上并不包含这些输入。请注意,对于 <form> 元素,name 属性是 deprecated

相反,您可以在 表单中添加一个隐藏的 <input> ,如下所示:

<form method="POST">
    {% csrf_token %}
    {{ formlog|crispy }}
    <input type="hidden" name="login" value="true" />
    <button class="log-button first" type="submit">Login</button>
</form>

此外,

formlog = auth_views.LoginView.as_view(template_name='main/index.html')

视图保存到formlog,而不是表格,因此调用formlog.is_valid()会导致错误。

而不是

elif 'login' in request.POST:
    if formlog.is_valid():
        formlog.save()
        username = form.cleaned_data.get('username')
        messages.success(request, f'Your account has been created! You are now able to log in')
        return redirect('main')

你可能只需要做

elif 'login' in request.POST:
    log_view = auth_views.LoginView.as_view(template_name='main/index.html')
    log_view(request)

调用 is_valid()save() 和执行重定向都已由 LoginView 完成。如果您仍想执行自定义 message.success(),则必须覆盖一个或多个 LoginView 方法,但这是另一个话题。

更新:

您还需要将视图中的这一行:formlog = auth_views.LoginView.as_view(template_name='main/index.html')(在 return render... 之前)更改为:

formlog = AuthenticationForm(request)

将此行放在 else 块之外。

同时在 views.py:

顶部添加表单导入
from django.contrib.auth.forms import AuthenticationForm

此更改是必需的,因为模板需要表单对象(默认情况下 LoginViewAuthenticationForm)而不是视图对象。更新后的视图函数将如下所示:

from django.contrib.auth.forms import AuthenticationForm

def index(request):
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if 'signup' in request.POST:
            if form.is_valid():
                form.supervalid()
                form.save()
                username = form.cleaned_data.get('username')
                messages.success(request, f'Dear {username} you have been created a new accound!')
                return redirect('main')
        elif 'login' in request.POST:
            log_view = auth_views.LoginView.as_view(template_name='main/index.html')
            log_view(request)
    else:
        form = UserRegisterForm()
    formlog = AuthenticationForm(request)
    return render(request, 'main/index.html', {'form': form, 'formlog': formlog})

请注意,这可以通过在登录凭据无效时提供反馈来改进。实际上,如果提供的凭据不起作用,此更新后的代码只会重新加载空白登录表单。