使用Docker加上Nginx、Django和RDS,完成WEB应用步骤④:尝试登录与注销功能

开场白

我会记录下自己独学编写儿童成长应用程序的过程。如果有任何错误或疏漏之处,请您联系我。
① 在进入Django的欢迎页面之前
② 在通过Nginx进入Django的欢迎页面之前
③ 创建自定义用户并进入admin
④ 尝试登录和注销 <– 这部分是
⑤ 创建用户注册(登录)功能
⑥ 为每个用户添加数据注册功能 – 创建、读取、更新
⑦ 为每个用户添加数据注册功能 – 删除
⑧ 上传图片文件
⑨ 记录身高和体重,附带批量删除功能
⑩ 尝试绘制成长曲线图
⑪ 部署到生产环境并进行各种调整

目标。

让我们创建登录/登出功能。

准备HTML

因为每个应用程序都要将Django的模板分开变得很麻烦,
所以决定将模板放在一个地方。最终形式如下(细节略去)。

.
├── docker-compose.yml
├── nginx
│   ├── conf
│   │   └── mysite_nginx.conf
│   └── uwsgi_params
├── src
│   ├── manage.py
│   ├── mysite
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   ├── templates
│   │   ├── base.html
│   │   └── users
│   │       ├── login.html
│   │       ├── mypage.html
│   │       └── signup.html
│   └── users
│       ├── admin.py
│       ├── apps.py
│       ├── forms.py
│       ├── models.py
│       ├── urls.py
│       └── views.py
├── static
│   └── 略
└── web
    ├── Dockerfile
    └── requirements.txt

为了告诉你模板的位置,我会修改setting.py文件。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #変更
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

CSS中的bootstrap很方便且不错。
因为bootstrap有适用于django的版本,所以使用它。

Django==2.2.2
psycopg2==2.8.4
uwsgi==2.0.17
django-bootstrap4==1.1.1 #追加

将设置添加到APPS,并添加到模板指定。


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users.apps.UsersConfig',
    'bootstrap4', #追加
]
()
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            'builtins':[ #追加
                'bootstrap4.templatetags.bootstrap4',
            ],
        },
    },
]

HTML(服务器)

基础的HTML。使用Bootstrap使其具备响应式布局。

{% load static %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}

<html>
    <head>
        <title>kids Growth</title>
        <link rel="stylesheet" href="{% static 'css/kidsGrowth.css' %}">
        {% block extra_js %}{% endblock %}
       </head>
    <body>
        <!-- Navigation -->
        <nav class="navbar navbar-expand-sm navbar-dark bg-dark mt-3 mb-3">
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav4" aria-controls="navbarNav4" aria-expanded="false" aria-label="Toggle navigation">
              <span class="sr-only">メニュー</span>  
              <span class="navbar-toggler-icon"></span>
            </button>
            <a class="navbar-brand" href="">Kids Growth</a>
            <div class="collapse navbar-collapse" id="navbarNav4">
                <ul class="navbar-nav">
                  <li class="nav-item">
                      <a class="nav-link" href="">メニュー1</a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link" href="">メニュー2</a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link" href="">メニュー3</a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link" href="{% url 'users:mypage'%}">マイページ</a>
                  </li>
                  {% if user.is_authenticated %}
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'users:logout'%}">ログアウト</a>
                    </li>
                  {% else %}
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'users:login'%}">ログイン</a>
                    </li>
                  {% endif %}
                </ul>
            </div>
        </nav>    

        <div class="content container">
          {% block content %}
          {% endblock %}
        </div>
    </body>
</html>

我的页面。(仅显示用户名)
设定为登录后跳转到此处。
{{ user }}将在稍后从视图传递过来。

{% extends 'base.html' %}

{% block content %}

<div class="col-md-12 col-lg-5">
    <h2>My Page</h2>

    <br>
    <br>

    <table class = "table">
      <tr>
        <td>ユーザー名</td>
        <td>{{ user }}</td>
      </tr>
    </table>


</div>

{% endblock content %}

只需使用名称为”form”的表单,通过bootstrap_form进行美观的格式化处理。
我们提供了用户注册的链接,但该功能在后续操作中实现。

{% extends 'base.html' %}

{% block content %}

{{ form.media }}

<div class="col-md-12 col-lg-5">
    <h2>Login</h2>
        <form action="" method="POST">
                {{ form.non_field_errors }}
                {% bootstrap_form form %}
                <hr>
                <button type="submit" class="btn btn-success btn-lg btn-block" >ログイン</button>
                {% csrf_token %}
        </form>


        <a href="{% url 'users:signup' %}">ユーザー登録</a>

</div>
{% endblock %}

表格

通过继承AuthenticationForm,作为Form的一部分,
实现登录功能。只需这样简单的一步。非常方便。

class LoginForm(AuthenticationForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

观看

由于登录和登出有各自的视图,所以需要继承它们。
加上@login_required装饰器的函数只能在登录状态下调用。
暂时只需要获取已登录用户的姓名,然后将其返回给模板。

顺便提一下,如果将登录类设置为”login”,那么后面创建”Signup”函数时可能会与预设的命名冲突,导致无法解除错误,命名稍显尴尬。

from .forms import LoginForm
from django.shortcuts import render, redirect
from django.contrib.auth.views import LoginView, LogoutView
from django.contrib.auth.decorators import login_required

#ログイン
class login_mypage(LoginView):
    form_class = LoginForm
    template_name = 'users/login.html'

#ログアウト
class logout(LogoutView):
    template_name = 'users/login.html'

#マイページ
@login_required
def mypage(request):
    user_name = request.user
    params = {
        'user' : user_name,
    }
    return render(request, 'users/mypage.html',params)

网址

在项目的urls文件中,加载每个应用程序的urls。

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('users.urls')),
]

对于每个应用程序定义的URL模式,决定相应的视图。

app_name = 'users'

urlpatterns = [
    path('', views.mypage, name='mypage'),
    path('mypage/', views.mypage, name='mypage'),
    path('login/', views.login_mypage.as_view(), name='login'),
    path('logout/', views.logout.as_view(), name='logout'),
]

设置.py

请添加以下内容。登录链接在这里哦~
登录后请先访问这里哦~
决定显示哪个页面当您注销登录的时候。

LOGIN_URL = 'users:login'
LOGIN_REDIRECT_URL = 'users:mypage'
LOGOUT_REDIRECT_URL = 'users:login'

上来

登录页面和登录后的页面。

スクリーンショット 2020-02-11 20.45.49.png
bannerAds