在这一部分,我们将进一步扩展我们的 Django 应用,添加用户登录和注销的功能,同时保护一些视图,确保只有登录用户才能访问。以下是第五部分的步骤:

步骤1:更新视图

在 helloworldapp/views.py 中,添加新的视图函数,用于登录和注销:
# helloworldapp/views.py

from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render, redirect
from .models import Greeting, CustomUser
from .forms import GreetingForm, CustomUserCreationForm

@login_required
def hello(request):
    if request.method == 'POST':
        form = GreetingForm(request.POST)
        if form.is_valid():
            message = form.cleaned_data['message']
            Greeting.objects.all().delete()
            Greeting.objects.create(message=message)
            return redirect('hello')
    else:
        form = GreetingForm()

    greeting = Greeting.objects.first()
    return render(request, 'helloworldapp/hello.html', {'greeting': greeting, 'form': form})

def register(request):
    if request.method == 'POST':
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('login')
    else:
        form = CustomUserCreationForm()

    return render(request, 'registration/register.html', {'form': form})

def user_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(request, username=username, password=password)
        if user:
            login(request, user)
            return redirect('hello')
        else:
            return render(request, 'registration/login.html', {'error_message': 'Invalid login credentials.'})
    else:
        return render(request, 'registration/login.html')

@login_required
def user_logout(request):
    logout(request)
    return redirect('login')

步骤2:更新 URL 路由

在 helloworldapp/urls.py 中,添加 URL 路由用于登录和注销页面:
# helloworldapp/urls.py

from django.urls import path
from .views import hello, register, user_login, user_logout

urlpatterns = [
    path('hello/', hello, name='hello'),
    path('register/', register, name='register'),
    path('login/', user_login, name='login'),
    path('logout/', user_logout, name='logout'),
]

步骤3:更新主 URL 路由

在 helloworldproject/urls.py 中,确保 URL 路由配置正确:
# helloworldproject/urls.py

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('helloworld/', include('helloworldapp.urls')),
    path('', include('django.contrib.auth.urls')),  # 包含内置的用户认证视图
]

步骤4:创建登录模板

在 helloworldapp/templates/registration/login.html 中,创建一个模板文件用于用户登录:
<!-- helloworldapp/templates/registration/login.html -->

{% extends 'base.html' %}

{% block content %}
  <h2>Login</h2>
  {% if error_message %}
    <p>{{ error_message }}</p>
  {% endif %}
  <form method="post" action="{% url 'login' %}">
    {% csrf_token %}
    <label for="username">Username:</label>
    <input type="text" name="username" required><br>
    <label for="password">Password:</label>
    <input type="password" name="password" required><br>
    <button type="submit">Login</button>
  </form>
{% endblock %}

步骤5:更新主模板

在 helloworldapp/templates/base.html 中,更新主模板以显示登录状态和相应的链接:
<!-- helloworldapp/templates/base.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello Django</title>
</head>
<body>
    {% if user.is_authenticated %}
      <p>Welcome, {{ user.username }}! <a href="{% url 'logout' %}">Logout</a></p>
    {% else %}
      <p><a href="{% url 'login' %}">Login</a> | <a href="{% url 'register' %}">Register</a></p>
    {% endif %}

    {% block content %}{% endblock %}
</body>
</html>

步骤6:运行开发服务器

确保你的开发服务器正在运行:
python manage.py runserver

现在,你可以在浏览器中访问 http://127.0.0.1:8000/helloworld/hello/ 查看主页面,或者访问 http://127.0.0.1:8000/helloworld/login/ 进行用户登录。

这样,你的 Django 应用已经包含了用户登录和注销功能。在后续学习中,你可以进一步了解 Django 的用户权限、视图装饰器等更高级的主题。


转载请注明出处:http://www.zyzy.cn/article/detail/7127/Django