1. 程式人生 > >pycharm python3.6 Django2.0 mysql 使用者登入與註冊系統

pycharm python3.6 Django2.0 mysql 使用者登入與註冊系統

一、建立專案

1.1.建立專案和app

django-admin startproject mysite_login

python manage.py startapp login

1.2.設定時區和語言

Django預設使用美國時間和英語,在專案的settings檔案中,如下所示:

複製程式碼
LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True
複製程式碼

我們把它改為亞洲/上海時間和中文

複製程式碼
LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N 
= True USE_L10N = True USE_TZ = False
複製程式碼

1.3.啟動

執行測試一下工程,在本機的瀏覽器中訪問http://127.0.0.1:8000/

 二、設計資料模型

 2.1.資料庫模型設計

 作為一個使用者登入和註冊專案,需要儲存的都是各種使用者的相關資訊。很顯然,我們至少需要一張使用者表User,在使用者表裡需要儲存下面的資訊:

  • 使用者名稱
  • 密碼
  • 郵箱地址
  • 性別
  • 建立時間

 進入login/models.py,程式碼如下

複製程式碼
# login/models.py

from django.db import models


class User(models.Model):
    '''使用者表'''

    gender 
= ( ('male',''), ('female',''), ) name = models.CharField(max_length=128,unique=True) password = models.CharField(max_length=256) email = models.EmailField(unique=True) sex = models.CharField(max_length=32,choices=gender,default='') c_time = models.DateTimeField(auto_now_add=True)
def __str__(self): return self.name class Meta: ordering = ['c_time'] verbose_name = '使用者' verbose_name_plural = '使用者'
複製程式碼

各欄位含義:

  • name必填,最長不超過128個字元,並且唯一,也就是不能有相同姓名;
  • password必填,最長不超過256個字元(實際可能不需要這麼長);
  • email使用Django內建的郵箱型別,並且唯一;
  • 性別使用了一個choice,只能選擇男或者女,預設為男;
  • 使用__str__幫助人性化顯示物件資訊;
  • 元資料裡定義使用者按建立時間的反序排列,也就是最近的最先顯示;

注意:這裡的使用者名稱指的是網路上註冊的使用者名稱,不要等同於現實中的真實姓名,所以採用了唯一機制。如果是現實中可以重複的人名,那肯定是不能設定unique的。

 2.2.設定資料庫為Mysql

在settings.py修改

複製程式碼
import pymysql
.............
pymysql.install_as_MySQLdb()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',        #資料庫名字
        'USER': 'root',          #賬號
        'PASSWORD': '123456',      #密碼
        'HOST': '127.0.0.1',    #IP
        'PORT': '3306',                   #
    }
}
複製程式碼

  2.3.資料庫遷移

註冊app

複製程式碼
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'login',
]
複製程式碼

遷移到資料庫

python manage.py makemigrations

python manage.py migrate

三、admin後臺

3.1.在admin中註冊模型

複製程式碼
# login/admin.py

from django.contrib import admin
from . import models

admin.site.register(models.User)
複製程式碼

 3.2.建立超級管理員

python manage.py createsuperuser

然後再增加幾個測試使用者

 四、url路由和檢視

 前面我們已經建立好資料模型了,並且在admin後臺中添加了一些測試使用者。下面我們就要設計好站點的url路由、對應的處理檢視函式以及使用的前端模板了。

 4.1.路由設計

初步設想需要下面的四個URL:

 

考慮到登入系統屬於站點的一級功能,為了直觀和更易於接受,這裡沒有采用二級路由的方式,而是在根路由下直接編寫路由條目,同樣也沒有使用反向解析名(name引數)。

複製程式碼
# mysite_login/urls.py

from django.conf.urls import path
from django.contrib import admin
from login import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
    path('login/', views.login),
    path('register/', views.register),
    path('logout/', views.logout),
    path('captcha', include('captcha.urls'))
]
複製程式碼

4.2.架構初步檢視

路由寫好了,就進入login/views.py檔案編寫檢視的框架,程式碼如下:

複製程式碼
# login/views.py

from django.shortcuts import render,redirect

def index(request):
    pass
    return render(request,'login/index.html')

def login(request):
    pass
    return render(request,'login/login.html')

def register(request):
    pass
    return render(request,'login/register.html')

def logout(request):
    pass
    return redirect('/index/')
複製程式碼

我們先不著急完成檢視內部的具體細節,而是把框架先搭建起來。

4.3.建立HTML頁面檔案

在專案根路徑的templates目錄,再在templates目錄裡建立一個login目錄

templates/login目錄中建立三個檔案index.htmllogin.html以及register.html ,並寫入如下的程式碼:

index.html

複製程式碼
{% extends 'base.html' %}
{% block title %}主頁{% endblock %}
{% block content %}
    {% if request.session.is_login %}
    <h1>你好,{{ request.session.user_name }}!歡迎回來!</h1>
{% else %}
    <h1>你尚未登入,只能訪問公開內容!</h1>
{% endif %}
{% endblock %}
複製程式碼

login.html

複製程式碼
{% extends 'login/base.html' %}
{% load staticfiles %}
{% block title %}登入{% endblock %}
{% block css %}
    <link rel="stylesheet" href="{% static 'css/login.css' %}">
{% endblock %}


{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
          <form class='form-login' action="/login/" method="post">
{% if message %}
                  <div class="alert alert-warning">{{ message }}</div>
{% endif %}
              {% csrf_token %}
              <h2 class="text-center">歡迎登入</h2>
              <div class="form-group">
{{ login_form.username.label_tag }}
                  {{ login_form.username}}
              </div>
              <div class="form-group">
{{ login_form.password.label_tag }}
                  {{ login_form.password }}
              </div>
              <div class="form-group">
{{ login_form.captcha.errors }}
                  {{ login_form.captcha.label_tag }}
                  {{ login_form.captcha }}
              </div>
              <button type="reset" class="btn btn-default pull-left">重置</button>
              <button type="submit" class="btn btn-primary pull-right">提交</button>
          </form>
        </div>
    </div> <!-- /container -->
{% endblock %}
複製程式碼

register.html

複製程式碼
{% extends 'login/base.html' %}

{% block title %}註冊{% endblock %}
{% block content %}
    <div class="container">
        <div class="col-md-4 col-md-offset-4">
          <form class='form-register' action="/register/" method="post">
{% if message %}
                  <div class="alert alert-warning">{{ message }}</div>
{% endif %}

              {% csrf_token %}

              <h2 class="text-center">歡迎註冊</h2>
              <div class="form-group">
{{ register_form.username.label_tag }}
                  {{ register_form.username}}
              </div>
              <div class="form-group">
{{ register_form.password1.label_tag }}
                  {{ register_form.password1 }}
              </div>
              <div class="form-group">
{{ register_form.password2.label_tag }}
                  {{ register_form.password2 }}
              </div>
              <div class="form-group">
{{ register_form.email.label_tag }}
                  {{ register_form.email }}
              </div>
              <div class="form-group">
{{ register_form.sex.label_tag }}
                  {{ register_form.sex }}
              </div>
              <div class="form-group">
{{ register_form.captcha.errors }}
                  {{ register_form.captcha.label_tag }}
                  {{ register_form.captcha }}
              </div>
              <button type="reset" class="btn btn-default pull-left">重置</button>
              <button type="submit" class="btn btn-primary pull-right">提交</button>
          </form>
        </div>
    </div> <!-- /container -->
{% endblock %}
複製程式碼

可以看到如下圖的頁面:

5.2.引入Bootstrap

根目錄下新建一個static目錄,並將解壓後的bootstrap-3.3.7-dist目錄,整體拷貝到static目錄中,如下圖所示:

 

由於Bootstrap依賴JQuery,所以我們需要提前下載並引入JQuery下載地址

在static目錄下,新建一個css和js目錄,作為以後的樣式檔案和js檔案的存放地,將我們的jquery檔案拷貝到static/js目錄下。

 

然後開啟專案的settings檔案,在最下面新增配置,用於指定靜態檔案的搜尋目錄:

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

5.3.建立base.html模板

既然要將前端頁面做得像個樣子,那麼就不能和前面一樣,每個頁面都各寫各的,單打獨鬥。一個網站有自己的統一風格和公用部分,可以把這部分內容集中到一個基礎模板base.html中。現在,在根目錄下的templates中新建一個base.html檔案用作站點的基礎模板。

{% static '相對路徑' %}這個Django為我們提供的靜態檔案載入方法,可以將頁面與靜態檔案連結起來

 最後,base.html內容如下:

複製程式碼
{% load staticfiles %}
<html >
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- 上述3個meta標籤*必須*放在最前面,任何其他內容都*必須*跟隨其後! -->
<title>{% block title %}base{% endblock %}</title>
<!-- Bootstrap -->
<link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.css' %}" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
{% block css %}{% endblock %}
  </head>
  <body>
    <nav class="navbar navbar-default">
      <div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#my-nav" aria-expanded="false">
            <span class="sr-only">切換導航條</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Mysite</a>
        </div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="my-nav">
          <ul class="nav navbar-nav">
            <li class="active"><a href="/index/">主頁</a></li>
          </ul>
          <ul class="nav navbar-nav navbar-right">
            <li><a href="/login">登入</a></li>
            <li><a href="/register/">註冊</a></li>
          </ul>
        </div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
{% block content %}{% endblock %}


    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="{% static 'js/jquery-3.2.1.js' %}"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.js' %}"></script>
  </body>
</html>
複製程式碼

簡要說明:

  • 通過頁面頂端的{% load staticfiles %}載入後,才可以使用static方法;
  • 通過{% block title %}base{% endblock %},設定了一個動態的頁面title塊;
  • 通過{% block css %}{% endblock %},設定了一個動態的css載入塊;
  • 通過{% block content %}{% endblock %},為具體頁面的主體內容留下介面;
  • 通過{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}將樣式檔案指向了我們的實際靜態檔案,下面的js指令碼也是同樣的道理。

static/css目錄中新建一個login.css樣式檔案,這裡簡單地寫了點樣式,

複製程式碼
body {
  background-color: #eee;
}
.form-login {
  max-width: 330px;
  padding: 15px;
  margin: 0 auto;
}
.form-login .form-control {
  position: relative;
  height: auto;
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: