一. Django必要的知識點補充
1. templates和static文件夾及其配置
1.1 templates文件夾
所有的HTML文件默認都放在templates文件夾下。
1.2 static文件夾
所有的靜態文件(css,js,前端第三方類庫)默認都放在static文件夾下。我們需要手動創建static文件夾(跟app處於同級目錄,每個app文件夾里面也可以有自己的static文件夾),然后里面再建兩個文件夾:css和js)。
首先HTML頁面訪問外部資源有兩個方式,一是cdn,二是本地。當我們服務端用的本地的時候,客戶端是訪問不到的(如果說本地靜態文件夾路徑是D:\mydjango/static,客戶端訪問時可能就會變成127.0.0.1/8080/mydjango/static,自然是訪問不到。)
為了讓客戶端能訪問到靜態文件(比如我們用本地導入的Bootstrap),我們需要修改Django的settings.py:
1. 拉到settings.py最下面
2. 在其下面添加STATICFILES_DIRS = [ ],里面存放靜態文件夾的路徑。
STATIC_URL = '/static/' #接口前綴,規定了你HTML界面導入靜態文件的路徑前綴,/變量名/:變量名隨意取 #但默認情況下接口前綴跟文件夾名字一樣 #靜態文件設置 STATICFILES_DIRS = [ #靜態文件夾路徑,可以有多個,因為每個app也可以有自己的static文件夾 os.path.join(BASE_DIR, 'static') ] #暴露給外界,能夠訪問服務器靜態文件下所有的資源 #STATICFILES_DIRS里面可以寫多個靜態文件夾的路徑 #瀏覽器訪問時會依次從靜態文件夾路徑查找資源,找到就停止,如果都沒找到就報錯,
3. 將HTML文件中導入靜態文件的地方路徑也稍作修改,路徑開始都換成接口前綴,后面跟static文件下你要導入的文件的相對路徑即可。
2. 關於form表單提交數據
2.1 提交數據的兩種方式
第一種:submit
<input type="submit">
第二種:button按鈕
<button>button</button>
2.2 form表單提交數據的地址指定方式
首先地址是由action屬性來控制的。
第一種方式:全路徑
<form action="http://127.0.0.1:8000/login/">
第二種方式:只寫路徑后綴(瀏覽器會自動拿當前頁面的host、ip幫你補全路徑)
<form action="/login/">
第三種方式:不寫,默認是提交至當前頁面。
注意:form表單默認是GET請求,需要向后端提交form表單數據時,我們需要通過method屬性改為POST。
<form action="/login/" method='POST'>
單單這樣還不夠,為了POST請求不報錯,我們需要先將Django的settings.py中注釋掉一個中間件。
如果不注釋的話可能會出現以下問題:
3. 后端獲取前端數據的方法
首先我們需要能夠判斷瀏覽器是單純想獲取頁面信息還是有數據提交給我們。這就需要用到request.method方法,它能獲取當前客戶端的請求方式(GET、POST)。
def login(request): print(request.method) if request.method == 'POST': print(request.POST) #可以看做是存放客戶端POST請求提交的所有數據的字典{key:value} # request.POST:< QueryDict: {'username': ['jason'], 'password': ['123']} > print(request.POST.get('username')) #雖然value是列表,但是默認取其中的最后一個數據 print(request.POST['username']) #拿到的也同.get一樣,不推薦使用該方法獲取數據 print(request.POST.getlist('username')) #一次性獲取value列表所有數據 return HttpResponse('OK') print(request.GET) #跟request.POST獲取數據方式一樣 return render(request, 'login.html')
注意:獲取value列表里面所有元素需要使用getlist,應用場景:用戶的愛好--多選框
get只能拿到value列表的最后一個元素。前端GET請求最多攜帶數據為4KB。
還有一點要提的是,不論你的請求方式是GET或者是POST,只要你的路徑攜帶了信息,后端都可以通過request.GET來得到(比如:127..0.1:8080/index/?id=1,我們可以通過request.GET.get('id')拿到id)。這就意味着前端請求方式是POST得時候,后端也是可以通過request.GET來得到消息,舉個實例。
當我們一些數據想要給后端,但是又不想讓其顯示在前端界面的時候,有兩種方式可以實現。
方式一:將id放在form表單action的URL后面
<form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
方式二:利用input隱藏
<input type="hidden" name="edit_id" value="{{ user_obj.pk }}">
二. Django連接數據庫
Django的settings.py里面提供了連接數據庫的入口,要實現連接不同的數據庫,只要修改其中的參數等信息即可。
1. sqlite3數據庫
是Django自帶的一個小型數據庫,可以用來做本地測試,如果數據量不大的話。
2. 連接MySQL數據庫
1. 修改配置文件
修改上述DATABASES中的參數(鍵必須都是大寫)
2. 告訴django用pymysql替換它默認的mysql_db模塊連接數據庫
因為mysql_db現在已經沒用了,所以需要替換模塊。
在項目文件夾下的__init__.py或者是應用文件夾下的__init__.py中加入以下語句。
#加下列語句,固定寫法 import pymysql pymysql.install_as_MySQLdb()
3. 點擊pycharm右側的database,選擇要連接的數據庫
4. 最后一步准備
這樣數據庫就成功連接上了,如果中途沒出現什么意外的話。
3. 數據庫遷移(同步)命令
Django的ORM雖然不會自動幫我們創建庫,但是會幫我們自動創建表,然而創建的過程還是需要我們配合的,並非全自動。
還需要在命令行窗口(比如pycharm里的terminal)輸入以下命令:
python3 manage.py makemigrations #數據庫變動的記錄(並不會幫你創建表) python3 manage.py migrate #將你的數據庫變動同步到數據庫中(這下才是真正創建表了)
數據庫遷移命令執行完畢后,表創建完成了,不過你可能會發現它幫我們創建了其他的表,不要慌,正常現象。
注意:
- 數據庫遷移記錄都存放在migrations文件夾下。
- tools選項中的Run manage.py Task敲命令更方便,因為有提示,而且不需要輸入前面的python3 manage.py。(當然前期不推薦這么干,要不然完整命令都忘了,面試被問到了咋整)
- 只要修改了模型層(models.py)的與表相關的任何數據,都必須重新執行數據庫遷移命令。
- 一個Django項目用一個庫,不要多個Django項目共用一個庫!!!
三. Django中的ORM(初級知識)
1. ORM概念
對象關系映射(英語:(Object Relational Mapping,簡稱ORM,或O/RM,或O/R mapping),是一種程序技術,用於實現面向對象編程語言里不同類型系統的數據之間的轉換 。從效果上說,它其實是創建了一個可在編程語言里使用的--“虛擬對象數據庫”。
在ORM中,每一個類都映射數據庫中的一張表。ORM的類都寫在models.py中。
類 》》》 表
對象 》》》 表記錄
對象的屬性 》》》一條記錄某個字段對應的值
2. ORM對數據庫的增刪改查
操作數據庫,無非就是增刪改查,為了更好的演示,這里定義一個ORM類,然后假設前后端數據交互已完成,username和password均是從前端拿到的數據。
這里先提一個QuerySet對象,Django操作數據庫時,查詢的all()和filter()方法返回的是QuerySet對象,有點像列表里面存放一個個對象,它可以用.query的方法獲取其內部的mysql語句。如果要獲取數據對象的話,可以用索引取,但是不推薦這么做,因為可能會報錯,通常我們用QuerySet.first()等方法取其中的數據對象。
class User(models.Model): # user表的主鍵字段名就是id,其實可以不寫,因為你不寫時Django默認會幫你創建一個字段名為id的主鍵 id = models.AutoField(primary_key=True) # varchar(32) name字段是varchar(32) CharField在定義的時候必須要加max_length參數 name = models.CharField(max_length=32) # varchar(16) name字段是varchar(32) CharField在定義的時候必須要加max_length參數 password = models.CharField(max_length=16)
2.1 增
方式一:
user_obj = models.User.objects.create(name=username,
password=password) #返回當前的數據對象本身
方式二:
user_obj = models.User(name=username, password=password) user_obj.save() # 對象調用save方法保存至數據庫
2.2 查
查全部數據:
user_list = models.User.objects.all() print(user_list) print(user_list.query) #只要是QuerySet對象,就能用.query獲取它內部的MySQL語句
根據條件查詢:
res = models.User.objects.filter(id=delete_id)
#這樣回來的是QuerySet對象,如果條件不存在返回空的QuerySet對象 res = models.User.objects.filter(id=delete_id).first()
#取出里面的第一個對象,雖然可以索引取,但是不推薦使用,而起不支持負索引取值
根據條件查詢直接拿一個數據對象(該方法不推薦使用,因為存在報錯的情況)
res = models.User.objects.get(id=edit_id) #如果id不存在會直接報錯
注意:get和filter相比,get能直接拿回一個數據對象,但是查詢條件不滿足時會報錯。而filter查詢條件滿足或者不滿足時返回的都是QuerySet對象,可以通過.first()、.last()取其中的數據對象,不存在報錯的情況。所以一般選擇用filter方法。
2.3 刪
models.User.objects.filter(id=delete_id).delete()
#會將該QuerySet里面的數據對象都刪除掉(會同步到數據庫)
2.4 改
#方式一(推薦使用該方式): models.User.objects.filter(id=edit_id).update(name=username, password=password) #方式二: user_obj = models.User.objects.filter(id=edit_id).first() user_obj.name = username user_obj.save()
注意:QuerySet點語法,點刪除和修改都會作用於對象內部所有的數據對象,類似於批量操作。
所以想要操作單個數據對象時,最好查時用能唯一標識一條數據的條件。
四. 簡單實現用戶的添加、刪除、修改操作
現在我們數據庫連接也會了,ORM也稍微知道了一點用法,就可以寫一點東西來讓知識點印象更深刻。
1. 用戶的注冊
首先思路是用戶在瀏覽器輸入用戶名、密碼,點注冊按鈕后,將輸入的數據提交給后端,后端從數據庫找相應的用戶信息是否存在。存在則返回用戶已存在,不存在則完成用戶的創建並返回注冊成功。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>register</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> .c1 { margin-top: 50px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4 c1"> <h2 class="text-center">注冊</h2> <form action="" method="post"> <p>username:<input type="text" name="username" class="form-control"></p> <p>password:<input type="password" name="password" class="form-control"></p> <input type="submit" value="注冊" class="btn btn-success"> </form> </div> </div> </div> </body> </html>

def register(request): if request.method == 'POST': name = request.POST.get('username') password = request.POST.get('password') user_obj = models.User.objects.filter(name=name, password=password).first() if not user_obj: models.User.objects.create(name=name, password=password) return HttpResponse('注冊成功') return HttpResponse('該用戶已存在') return render(request, 'register.html')
2. 登錄
思路跟注冊異曲同工,也是用戶在瀏覽器輸入用戶名、密碼,點點擊登錄按鈕后數據提交至后端,后端從數據庫找相應用戶信息,信息存在則返回登錄成功,否則返回用戶不存在。(如何明確告訴用戶是用戶名錯誤或者密碼錯誤?可以自己嘗試)。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> <style> .c1 { margin-top: 50px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4 c1"> <h2 class="text-center">登錄</h2> <form action="" method="post"> <p>username:<input type="text" name="username" class="form-control"></p> <p>password:<input type="password" name="password" class="form-control"></p> <input type="submit" value="登錄" class="btn btn-success"> </form> </div> </div> </div> </body> </html>

def login(request): if request.method == 'POST': name = request.POST.get('username') password = request.POST.get('password') user_obj = models.User.objects.filter(name=name, password=password).first() if not user_obj: return HttpResponse('該用戶不存在') return HttpResponse('登錄成功') return render(request, 'login.html')
3. 管理員添加、刪除、編輯用戶信息
首先要有一個管理員界面,管理員界面除了用戶信息,還應該有添加、刪除、編輯等按鈕,點擊相應的按鈕就能執行相應的功能,這里按鈕采用a標簽(用bootstrap裝飾成按鈕的樣子),不同按鈕對應不同的URL。
3.1 添加新用戶
這里采用最簡單的方式,點擊添加按鈕,跳轉至register視圖函數,注冊成功再重定向至用戶管理頁面。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>manage_user</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> .c1 { display: inline-block; } </style> </head> <body> <div class="container"> <div class="row" style="margin-top: 50px"> <div class="col-md-6 col-md-offset-3"> <a href="/register/" class="btn btn-success" style="margin-right: 75px">添加</a> <h2 class="text-center c1">用戶管理</h2> </div> </div> <div class="row"> <div class="col-md-6 col-md-offset-3"> <table class="table table-bordered table-striped table-hover"> <thead> <tr> <th class="text-center">id</th> <th class="text-center">name</th> <th class="text-center">password</th> <th class="text-center">operation</th> </tr> </thead> <tbody> {% for user_obj in user_list %} <tr class="text-center"> <td>{{user_obj.id}}</td> <td>{{user_obj.name}}</td> <td>{{user_obj.password}}</td> <td><a href="" class="btn btn-primary">編輯</a> <a href="" class="btn btn-danger">刪除</a></td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>

# 注冊視圖函數 def register(request): if request.method == 'POST': # 獲取前端提交的用戶名 name = request.POST.get('username') # 獲取前端提交的用戶密碼 password = request.POST.get('password') # 查找出相應用戶信息,filter返回的也是QuerySet對象,first方法取出其中第一個數據對象,可以為空 user_obj = models.User.objects.filter(name=name, password=password).first() # 用戶不存在則在數據庫中創建相應用戶信息記錄,並重定位至管理員界面 if not user_obj: models.User.objects.create(name=name, password=password) return redirect('/manage_user/') return HttpResponse('該用戶已存在') return render(request, 'register.html')

# 用戶管理界面視圖函數 def manage_user(request): # 取出所有用戶信息,all方法取出來的是QuerySet對象 user_list = models.User.objects.all() # render渲染前端頁面,locals將當前函數所有變量都發送至前端 return render(request, 'manage_user.html', locals())
3.2 刪除用戶
相比編輯用戶,刪除用戶顯得簡單點,那就先講刪除吧。當有多條用戶記錄時,如果讓后端知道我點刪除是想刪除哪條數據呢,這是一個問題。所以我們要想辦法把要刪除的用戶的一個標識告訴后端,比如說我一點刪除,向后端提交數據時順手把要刪除的用戶id帶給它。這就用到了上面一.3中提到的前端向后端隱式提交數據的兩種方式:1. 用input標簽隱藏 2. 放在URL里帶給后端。
這里采用第二種方法。(/delete_user/?user_id={{ user_obj.id }}) 注意:URL后面攜帶的數據有多個時,用&隔開。

# 刪除用戶信息視圖函數 def delete_user(request): user_id = request.GET.get('user_id') models.User.objects.filter(id=user_id).delete() return redirect('/manage_user/')
3.3 編輯用戶信息
編輯用戶信息,同理,我們需要得到用戶的唯一標識,這里也采用跟刪除用戶同樣的方法。當我們把用戶信息拿出來后,要先把數據渲染至前端(數據不給看還怎么編輯),然后想要修改的數據需要輸入(一提到這個就只有form表單的input了,然后input還有個value屬性,那么我們就可以定義input,然后將value設置為原用戶相應的信息,一舉兩得)。
3.4 代碼
應用文件夾下:

from django.shortcuts import render, HttpResponse, redirect from app01 import models # Create your views here. # 登錄視圖函數 def login(request): if request.method == 'POST': name = request.POST.get('username') password = request.POST.get('password') user_obj = models.User.objects.filter(name=name, password=password).first() if not user_obj: return HttpResponse('該用戶不存在') return HttpResponse('登錄成功') return render(request, 'login.html') # 注冊視圖函數 def register(request): if request.method == 'POST': # 獲取前端提交的用戶名 name = request.POST.get('username') # 獲取前端提交的用戶密碼 password = request.POST.get('password') # 查找出相應用戶信息,filter返回的也是QuerySet對象,first方法取出其中第一個數據對象,可以為空 user_obj = models.User.objects.filter(name=name, password=password).first() # 用戶不存在則在數據庫中創建相應用戶信息記錄,並重定位至管理員界面 if not user_obj: models.User.objects.create(name=name, password=password) return redirect('/manage_user/') return HttpResponse('該用戶已存在') return render(request, 'register.html') # 用戶管理界面視圖函數 def manage_user(request): # 取出所有用戶信息,all方法取出來的是QuerySet對象 user_list = models.User.objects.all() # render渲染前端頁面,locals將當前函數所有變量都發送至前端 return render(request, 'manage_user.html', locals()) # 刪除用戶信息視圖函數 def delete_user(request): user_id = request.GET.get('user_id') models.User.objects.filter(id=user_id).delete() return redirect('/manage_user/') # 編輯用戶信息視圖函數 def edit_user(request): user_id = request.GET.get('user_id') user_obj = models.User.objects.filter(id=user_id).first() if request.method == 'POST': name = request.POST.get('username') password = request.POST.get('password') models.User.objects.filter(id=user_id).update(name=name, password=password) return redirect('/manage_user/') return render(request, 'edit_user.html', locals())

from django.db import models # Create your models here. class User(models.Model): name = models.CharField(max_length=32) password = models.CharField(max_length=32)

import pymysql pymysql.install_as_MySQLdb()
項目文件夾下:

"""edit_user2 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^register/', views.register), url(r'^manage_user/', views.manage_user), url(r'^delete_user/', views.delete_user), url(r'^edit_user/', views.edit_user), ]

""" Django settings for edit_user2 project. Generated by 'django-admin startproject' using Django 1.11.11. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'm7hja%y&udo+^wbikt7e#9df5wk##-+vmfh3^(8i5!_ll(6=vx' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'edit_user2.urls' 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', ], }, }, ] WSGI_APPLICATION = 'edit_user2.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'user_db', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', 'PASSWORD': 'root' } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ]
templaets文件夾下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> <style> .c1 { margin-top: 50px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4 c1"> <h2 class="text-center">登錄</h2> <form action="" method="post"> <p>username:<input type="text" name="username" class="form-control"></p> <p>password:<input type="password" name="password" class="form-control"></p> <input type="submit" value="登錄" class="btn btn-success"> </form> </div> </div> </div> </body> </html>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>register</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> .c1 { margin-top: 50px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4 c1"> <h2 class="text-center">注冊</h2> <form action="" method="post"> <p>username:<input type="text" name="username" class="form-control"></p> <p>password:<input type="password" name="password" class="form-control"></p> <input type="submit" value="注冊" class="btn btn-success"> </form> </div> </div> </div> </body> </html>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>manage_user</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <style> .c1 { display: inline-block; } </style> </head> <body> <div class="container"> <div class="row" style="margin-top: 50px"> <div class="col-md-6 col-md-offset-3"> <a href="/register/" class="btn btn-success" style="margin-right: 75px">添加</a> <h2 class="text-center c1">用戶管理</h2> </div> </div> <div class="row"> <div class="col-md-6 col-md-offset-3"> <table class="table table-bordered table-striped table-hover"> <thead> <tr> <th class="text-center">id</th> <th class="text-center">name</th> <th class="text-center">password</th> <th class="text-center">operation</th> </tr> </thead> <tbody> {% for user_obj in user_list %} <tr class="text-center"> <td>{{user_obj.id}}</td> <td>{{user_obj.name}}</td> <td>{{user_obj.password}}</td> <td><a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-primary">編輯</a> <a href="/delete_user/?user_id={{ user_obj.id }}" class="btn btn-danger">刪除</a></td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>edit_user</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <h2 class="text-center">編輯用戶</h2> <form action="/edit_user/?user_id={{ user_obj.id }}" method="post"> <p>username:<input type="text" name='username' value="{{ user_obj.name }}" class="form-control"></p> <p>password:<input type="text" name='password' value="{{ user_obj.password }}" class="form-control"></p> <input type="submit" value="確認修改" class="btn btn-success"> <a href="/manage_user/" class="btn btn-danger">取消</a> </form> </div> </div> </div> </body> </html>