《Django开发从入门到实践》学习笔记

Django开发从入门到实践学习笔记

操作系统版本:Windows 10
python版本:Python 3.9.12
pip版本:pip 21.2.4
Django版本:Django 3.0.6

软件安装

python

官网下载python3

https://www.python.org/ftp/python/3.9.12/python-3.9.12-amd64.exe

在这里插入图片描述
注意勾选Add Python 3.9 to PATH

或应用商店中下载python3
在这里插入图片描述

查看安装情况

python -V
PS C:\Users\Thinkpad> python -V
Python 3.9.12

Django

安装Django

pip install django==3.0.6

查看安装情况

pip list
PS C:\Users\Thinkpad> pip list
Package    Version
---------- -------
Django     3.0.6

vscode

https://code.visualstudio.com/

在这里插入图片描述

书籍管理系统

项目定位

实现目标:藏书管理系统
项目定位:社团内部使用、用户量较少、使用频次相对低、功能单一且确定

功能需求

用户注册、用户分级、用户登录、书籍信息的添加、书籍信息的修改、书籍信息的删除、书籍信息的分类展示、书籍信息的查询

产品设计

URL方法静态页面用途顺序
index/views.indexindex.html用户进入系统时的欢迎页面1
sign_up/views.sign_upsign_up.html用户注册页面2
login/views.loginlogin.html用户登录页面3
logout/views.logout/用户退出页面4
change_password/views.change_passwordchange_password.html修改口令页面5
add_book/views.add_bookadd_book.html书籍信息的添加页面6
book_list/views.book_listbook_list.html书籍列表页面7

数据模型

书籍
字段类型名称默认值长度
nameCharField书籍名称非空128bit
authorCharField作者可空64bit
priceFloatField书籍定价0.0/
publish_dateDateTimeField出版日期可空/
cateoryCharField书籍分类未分类32bit
create_datetimeDateTimeField书籍添加时间auto_now_add/
用户

使用Django用户表auth_user

在这里插入图片描述

开始实践

创建项目和应用

创建BookManagement项目

cd C:\Code
django-admin startproject BookManagement

创建management应用

cd BookManagement
django-admin startapp management

打开vscode–>文件(File)–>打开文件夹(Open Folder)–>C:\Code\BookManagement–>确定–>终端(Terminal)–>新建终端(New Terminal)

在这里插入图片描述
启动Django开发服务器

python manage.py runserver
PS C:\Code\BookManagement> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the 
migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
April 27, 2022 - 19:44:29
Django version 3.0.6, using settings 'BookManagement.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

在这里插入图片描述

在settings.py中INSTALLED_APPS位置添加新建应用management

C:\Code\BookManagement\BookManagement\settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'management',  # 添加新建应用management
]
用户进入系统时的欢迎页面

编辑BookManagement项目urls.py,包含management应用urls.py

C:\Code\BookManagement\BookManagement\urls.py

"""BookManagement URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('management.urls')),  # 将management应用的URL设置包含到项目的URL设置中
]

创建并编辑management应用urls.py

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),  # 用户进入系统时的欢迎页面 
    path('index/', views.index, name='homepage'),  # 用户进入系统时的欢迎页面 
]

C:\Code\BookManagement\management\views.py

def index(request):
    return render(request,"management/index.html")

在BookManagement项目下创建templates文件夹,再到templates文件夹中为management应用创建management子目录,即BookManagement-templates-management

设置settings.py中TEMPLATES-DIRS,添加templates

C:\Code\BookManagement\BookManagement\settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 添加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',
            ],
        },
    },
]

在BookManagement-templates-management下创建index.html作为主页

BookManagement-templates-management-index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主页</title>
    主页
</head>
<body>
</body>
</html>

访问http://127.0.0.1:8000能够正常访问确认路由配置正常

在这里插入图片描述
需要使用Bootstrap3快速编写前端样式,选择Bootstrap版本下载Bootstrap3

在这里插入图片描述选择用于生产环境的Bootstrap部署方式
在这里插入图片描述

在C:\Code\BookManagement\management\下创建static目录,放置Bootstrap3静态文件css、fonts、js等

C:\Code\BookManagement\templates\management\index.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>主页</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
    <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="" class="navbar-brand">Library</a>
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage" class="active">
                        <a href="">主页</a>
                    </li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="/sign_up/">注册</a></li>
                    <li><a href="/login/">登录</a></li>
                </ul>
            </div>
    </nav>
    <header class="jumbotron subhead" id="header-base">
        <div class="container">
            <h1>图书管理系统</h1>
            <h3>&emsp;&emsp;知识改变命运</h3>
        </div>
    </header>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2 well">
                <h2>&emsp;&emsp;欢迎使用图书管理系统</h2>
                <h2>&emsp;&emsp;请注册登录后使用</h2>
                <h3 class="text-center">Email:<span class="text-info">Library@163.com</span></h3>
            </div>
        </div>
    </div>
    <div class="container">
        <p class="text-center">©All rights reserved</p>
        <h5 class="text-center">Powerd by&nbsp;<a href="http://127.0.0.1:8000/">Library</a></h5>
    </div>
</body>

</html>

在这里插入图片描述
将index.html根据结构拆分navbar.html、index.html

C:\Code\BookManagement\templates\management\navbar.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{% block title%}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
    <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="" class="navbar-brand">Library</a>
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage" class="active">
                        <a href="">主页</a>
                    </li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="/sign_up/">注册</a></li>
                    <li><a href="/login/">登录</a></li>
                </ul>
            </div>
    </nav>
{% block content %}
{% endblock %}
</body>

</html>

C:\Code\BookManagement\templates\management\index.html

{% extends "management/navbar.html" %}

{% block title %}主页{% endblock %}

{% block content %}
    <header class="jumbotron subhead" id="header-base">
        <div class="container">
            <h1>图书管理系统</h1>
            <h3>&emsp;&emsp;知识改变命运</h3>
        </div>
    </header>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2 well">
                <h2>&emsp;&emsp;欢迎使用图书管理系统</h2>
                <h2>&emsp;&emsp;请注册登录后使用</h2>
                <h3 class="text-center">Email:<span class="text-info">Library@163.com</span></h3>
            </div>
        </div>
    </div>
    <div class="container">
        <p class="text-center">©All rights reserved</p>
        <h5 class="text-center">Powerd by&nbsp;<a href="http://127.0.0.1:8000/">Library</a></h5>
    </div>
{% endblock %}

在这里插入图片描述

用户注册页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),  # 添加用户注册页面
]

在views.py中追加sign_up

C:\Code\BookManagement\management\views.py

def sign_up(request):
    return render(request,"management/sign_up.html")

在BookManagement-templates-management中新建sign_up.html

C:\Code\BookManagement\templates\management\sign_up.html

{% extends "management/navbar.html" %}

{% block title %}注册{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3 col-sm-10 col-sm-offset-1">
                <form method="POST" role="form" class="form-horizontal">
                    {% csrf_token %}
                    <h1 class="form-signin-heading text-center">请注册</h1>
                    <div class="form-group">
                        <label for="id_username" class="col-md-3 control-label">用户名:</label>
                        <div class="col-md-9">
                            <input type="text" class="form-control" id="id_username" required name="username" autofocus>
                            <span class="help-block">用于登录,可以包括大小写字母和下划线。</span>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_password" class="col-md-3 control-label">口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_password" required name="password">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_repassword" class="col-md-3 control-label">重复口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_repassword" required name="repassword">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_email" class="col-md-3 control-label">电子邮件:</label>
                        <div class="col-md-9">
                            <input type="text" class="form-control" id="id_email" required name="email">
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-9 col-md-offset-3">
                            <button class="btn btn btn-primary btn-block" type="submit" id="id_submit">注册</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

在这里插入图片描述
开始实现后端

用户表使用Django自带的数据表

python manage.py makemigrations
python manage.py migrate
python manage.py runserver
PS C:\Code\BookManagement> python manage.py makemigrations
PS C:\Code\BookManagement> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

在views.py添加

C:\Code\BookManagement\management\views.py

from django.contrib.auth.models import User
from django.shortcuts import redirect

def sign_up(request):
    if request.method=="POST":
        username=request.POST.get('username','')
        password=request.POST.get('password','')
        repassword=request.POST.get('repassword','')
        email=request.POST.get('email','')
        if password=='' or repassword=='':
            state='empty'
        elif password != repassword:
            state='repeat_error'
        else:
            if User.objects.filter(username=username):
                state='user_exist'
            else:
                new_user=User.objects.create_user(username=username,password=password,email=email)
                new_user.save()
                state='success'
                return redirect("/index/")
    return render(request,"management/sign_up.html")

在这里插入图片描述
能够添加用户了,添加成功后会跳转到index,添加未成功则保持当前界面

用户登录页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),  # 添加用户登录页面
]

在views.py中追加login

C:\Code\BookManagement\management\views.py

def login(request):
    return render(request,"management/login.html")

在BookManagement-templates-management中新建login.html

C:\Code\BookManagement\templates\management\login.html

{% extends "management/navbar.html" %}

{% block title %}登录{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3 col-sm-10 col-sm-offset-1">
                <form method="POST" role="form" class="form-horizontal">
                    {% csrf_token %}
                    <h1 class="form-signin-heading text-center">请登录</h1>
                    <div class="form-group">
                        <label for="id_username" class="col-md-3 control-label">用户名:</label>
                        <div class="col-md-9">
                            <input type="text" class="form-control" id="id_username" required name="username" autofocus>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_password" class="col-md-3 control-label">口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_password" required name="password">
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-9 col-md-offset-3">
                            <button class="btn btn btn-primary btn-block" type="submit" id="id_submit">登录</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

在这里插入图片描述

开始实现后端

在views.py添加

C:\Code\BookManagement\management\views.py

from django.contrib.auth.models import User, auth

def login(request):
    if request.method == "POST":
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if username and password:
            user = auth.authenticate(username=username, password=password)
            if user is not None:
                auth.login(request, user)
                return redirect("/index/")
            else:
                state = 'not_exist_or_password_error'
    return render(request, "management/login.html")

能够登录了,添加成功后会跳转到index,添加未成功则保持当前界面

用户退出页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('logout/', views.logout, name='logout'),  # 添加用户退出页面
]

C:\Code\BookManagement\management\views.py

在BookManagement-management-views.py添加

def logout(request):
    auth.logout(request)
    return redirect("/index/")

退出无单独界面,成功退出后重定向至index

修改口令页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('change_password/', views.change_password, name='change_password'),  # 添加用户修改口令页面
]

在views.py中追加change_password

C:\Code\BookManagement\management\views.py

def change_password(request):
    return render(request,"management/change_password.html")

在BookManagement-templates-management中新建change_password.html

C:\Code\BookManagement\templates\management\change_password.html

{% extends "management/navbar.html" %}

{% block title %}修改口令{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3 col-sm-10 col-sm-offset-1">
                <form method="POST" role="form" class="form-horizontal">
                    {% csrf_token %}
                    <h1 class="form-signin-heading text-center">修改口令</h1>
                    <div class="form-group">
                        <label for="id_password" class="col-md-3 control-label">原口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_password" required name="password">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_newpassword" class="col-md-3 control-label">现口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_newpassword" required name="newpassword">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_confirmpassword" class="col-md-3 control-label">确认口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_confirmpassword" required name="confirmpassword">
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-9 col-md-offset-3">
                            <button class="btn btn btn-primary btn-block" type="submit" id="id_submit">确认修改</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

在这里插入图片描述
开始实现后端

在views.py添加

C:\Code\BookManagement\management\views.py

def change_password(request):
    if request.user.is_authenticated:
        if request.method == "POST":
            user = request.user
            password = request.POST.get('password', '')
            newpassword = request.POST.get('newpassword', '')
            confirmpassword = request.POST.get('confirmpassword', '')
            if user.check_password(password):
                if not newpassword:
                    state = 'empty'
                elif newpassword != confirmpassword:
                    state = 'repeat_error'
                else:
                    user.set_password(newpassword)
                    user.save()
                    state = 'success'
                    return redirect('/index/')
            else:
                state = 'password_error'
    return render(request, "management/change_password.html")

能够修改口令了,添加成功后会跳转到index,添加未成功则保持当前界面

书籍信息的添加页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('change_password/', views.change_password, name='change_password'),
    path('add_book/', views.add_book, name='add_book'),  # 添加书籍信息添加页面
]

在BookManagement-management-views.py中追加add_book

C:\Code\BookManagement\management\views.py

def add_book(request):
    return render(request,"management/add_book.html")

在BookManagement-templates-management中新建add_book.html

C:\Code\BookManagement\templates\management\add_book.html

{% extends "management/navbar.html" %}

{% block title %}添加书籍信息{% endblock %}

{% block content %}
<div class="container" style="height: 100px;"></div>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <form method="POST" role="form" class="form-horizontal">
                {% csrf_token %}
                <h1 class="form-signin-heading text-center">添加图书</h1>
                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_name" class="control-label">书名:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" class="form-control" id="id_name" required name="name" autofocus>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_author" class="control-label">作者:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" class="form-control" id="id_author" required name="author">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_category" class="control-label">类型:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" class="form-control" id="id_category" required name="category">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_price" class="control-label">价格:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" class="form-control" id="id_price" required name="price">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_pubdate" class="control-label">出版日期:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" class="form-control" id="id_pubdate" required name="publish_date">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                    </div>
                    <div class="col-md-9">
                        <button class="btn btn btn-primary btn-block" type="submit">提交</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
{% endblock %}

在这里插入图片描述
开始实现后端

创建数据表Book

C:\Code\BookManagement\management\models.py

from django.db import models

# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=128, verbose_name='书籍名称')
    author = models.CharField(max_length=64, blank=True, verbose_name='作者')
    price = models.FloatField(default=0.0, verbose_name='定价')
    publish_date = models.DateField(null=True, blank=True, verbose_name='出版日期')
    cateory = models.CharField(
        max_length=32, default='未分类', verbose_name='添加日期'
    )
    create_datetime = models.DateTimeField(
        auto_now_add=True, verbose_name='添加日期'
    )  # auto_now_add参数自动填充当前时间

    def __str__(self):  # 定义__str__方法后,在将模型对象作为参数传递给str()函数时会调用该方法返回相应的字符串
        return self.name
python manage.py makemigrations  # 更新数据表更改情况
python manage.py migrate  # 更新数据表
python manage.py runserver  # 启动
PS C:\Code\BookManagement> python manage.py makemigrations
Migrations for 'management':
  management\migrations\0001_initial.py
    - Create model Book
PS C:\Code\BookManagement> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, management, sessions
Running migrations:
  Applying management.0001_initial... OK

在views.py添加

C:\Code\BookManagement\management\views.py

from management import models

def add_book(request):
    if request.user.is_authenticated:
        if request.method == "POST":
            new_book = models.Book (
                name = request.POST.get('name', ''),
                author = request.POST.get('author', ''),
                price = request.POST.get('price', ''),
                publish_date = request.POST.get('publish_date', ''),
                cateory = request.POST.get('cateory', ''),
                create_datetime = request.POST.get('create_datetime', ''),
            )
            new_book.save()
            state='success'
            return redirect('/book_list/')
    return render(request,"management/add_book.html")

在这里插入图片描述

能够添加书籍信息了,添加成功后会跳转到还未编写的book_list,添加未成功则保持当前界面

书籍列表页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('change_password/', views.change_password, name='change_password'),
    path('add_book/', views.add_book, name='add_book'),
    path('book_list/', views.book_list, name='book_list'),  # 添加书籍列表页面
]

在views.py中追加book_list

C:\Code\BookManagement\management\views.py

def book_list(request):
    return render(request,"management/book_list.html")

在BookManagement-templates-management中新建book_list.html

C:\Code\BookManagement\templates\management\book_list.html

{% extends "management/navbar.html" %}

{% block title %}登录{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-10 col-md-offset-1">
               <div class="list-group">
                     <a href="/book_list/" class="list-group-item" id="id_category_all" style="text-align:center">全部图书</a>
                 </div>
            </div>
            <div class ="col-md-10 col-md-offset-1">
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>书名</th>
                            <th>作者</th>
                            <th>出版日期</th>
                            <th>定价</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for book in book_list %}
                            <tr>
                                <th>{{forloop.counter}}</th>
                                <th><a href="#">{{book.name}}</a></th>
                                <th>{{book.author}}</th>
                                <th>{{book.publish_date}}</th>
                                <th>{{book.price}}</th>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}

在这里插入图片描述

开始实现后端

在views.py添加

C:\Code\BookManagement\management\views.py

from management import models

def book_list(request):
    if request.user.is_authenticated:
        if request.method == "GET":
            book_list = models.Book.objects.all().only('name','author','publish_date','price')
            content={
                'book_list':book_list,
            }
            print(content)
            return render(request,"management/book_list.html",content)
    return render(request,"management/book_list.html")

在这里插入图片描述

能够展示书籍列表了

问题:
1.业务功能有限
2.用户体验不够友好
3.安全性不足
4.性能不足

一点优化

展示当前登录用户

当已登录时展示当前登录用户,当未登录时显示注册和登录

C:\Code\BookManagement\templates\management\navbar.html

                <ul class="nav navbar-nav navbar-right">
                    {% if user %}  # 当user不空时显示当前登录用户,点击时修改口令
                        <li><a href="/change_password/">{{user}}</a></li>
                    {% else %}  # 当user为空时显示注册和登录
                        <li><a href="/sign_up/">注册</a></li>
                        <li><a href="/login/">登录</a></li>
                    {% endif %}
                </ul>

C:\Code\BookManagement\management\views.py

def index(request):
    if request.user.is_authenticated:  #当用户已认证时返回user
        user = request.user
        content={
            'user':user,
        }
        return render(request, "management/index.html",content)
    return render(request, "management/index.html")

配置了index页面、book_list页面,但是无任何位置配置book_list页面跳转

C:\Code\BookManagement\templates\management\navbar.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{% block title%}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
	  <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	  <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="/index/" class="navbar-brand">Library</a>  <!-- 添加href跳转index -->
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage">
                        <a href="/index/">主页</a>  <!-- 添加href跳转index -->
                    </li>
                    <li id="book_list">  <!-- 添加显示book_list -->
                        <a href="/book_list/">书籍列表</a>  <!-- 添加href跳转book_list -->
                    </li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    {% if user %}
                        <li><a href="/change_password/">{{user}}</a></li>
                    {% else %}
                        <li><a href="/sign_up/">注册</a></li>
                        <li><a href="/login/">登录</a></li>
                    {% endif %}
                </ul>
            </div>
    </nav>
{% block content %}
{% endblock %}
</body>

</html>

在这里插入图片描述
书籍列表位置无添加书籍的功能位置

在这里插入图片描述

添加跳转书籍详情页面

添加书籍信息的添加页面的跳转位置

C:\Code\BookManagement\templates\management\book_list.html

{% extends "management/navbar.html" %}

{% block title %}登录{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-10 col-md-offset-1">
                <div class="list-group col-md-10">
                    <a href="/book_list/" class="list-group-item" id="id_category_all" style="text-align:center">全部图书</a>
                </div>
                <div class="list-group col-md-2">
                    <a href="/add_book/" class="list-group-item" id="id_category_all" style="text-align:center">添加书籍</a>  <!-- 添加书籍信息的添加页面的跳转位置 -->
                </div>
            </div>
            <div class ="col-md-10 col-md-offset-1">
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>书名</th>
                            <th>作者</th>
                            <th>出版日期</th>
                            <th>定价</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for book in book_list %}
                            <tr>
                                <th>{{forloop.counter}}</th>
                                <th><a href="#">{{book.name}}</a></th>
                                <th>{{book.author}}</th>
                                <th>{{book.publish_date}}</th>
                                <th>{{book.price}}</th>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}

在这里插入图片描述

添加跳转退出界面

添加退出登录页面的跳转

C:\Code\BookManagement\templates\management\navbar.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{% block title%}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
	  <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	  <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="/index/" class="navbar-brand">Library</a>
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage">
                        <a href="/index/">主页</a>
                    </li>
                    <li id="book_list">
                        <a href="/book_list/">书籍列表</a>
                    </li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    {% if user %}
                        <li><a href="/change_password/">{{user}}</a></li>
                        <li><a href="/logout/">退出</a></li>  <!-- 添加退出登录页面的跳转 -->
                    {% else %}
                        <li><a href="/sign_up/">注册</a></li>
                        <li><a href="/login/">登录</a></li>
                    {% endif %}
                </ul>
            </div>
    </nav>
{% block content %}
{% endblock %}
</body>

</html>

在这里插入图片描述

添加图书的位置未进行前端校验和后端校验

在这里插入图片描述

添加前端校验

进行前端校验

C:\Code\BookManagement\templates\management\add_book.html

{% extends "management/navbar.html" %}

{% block title %}添加书籍信息{% endblock %}

{% block content %}
<div class="container" style="height: 100px;"></div>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <form method="POST" role="form" class="form-horizontal">
                {% csrf_token %}
                <h1 class="form-signin-heading text-center">添加图书</h1>
                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_name" class="control-label">书名:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_name" required name="name" autocomplete="no" autofocus>  <!-- 添加maxlength、autocomplete=no -->
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_author" class="control-label">作者:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_author" required name="author" autocomplete="no">  <!-- 添加maxlength、autocomplete=no -->
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_category" class="control-label">类型:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_category" required name="category" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_price" class="control-label">价格:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="number" step="0.01" min="0" maxlength="200" class="form-control" id="id_price" required name="price" autocomplete="no">  <!-- 添加价格的类型为number,step=0.01 -->
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_pubdate" class="control-label">出版日期:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="date" class="form-control" id="id_pubdate" required name="publish_date" autocomplete="no">  <!-- 添加出版日期类型为date -->
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                    </div>
                    <div class="col-md-9">
                        <button class="btn btn btn-primary btn-block" type="submit">提交</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
{% endblock %}

在这里插入图片描述
在这里插入图片描述

添加后端校验

C:\Code\BookManagement\management\views.py

class cleandata():
    def TypeNum(data):
        try:
            return int(data)
        except:
            return int(0)
    
    def TypeFloat(data):
        try:
            return float(data)
        except:
            return float(0.00)
    
    def TypeEmail(data):
        try:
            return email(data)
        except:
            return email("@163.com")
    
    def TypeUsername(data):
        try:
            return tostring(data).replace(["'","<",">","#"],"")
        except:
            return None
    
    def TypeChar(data):
        try:
            return data.replace("'","")
        except:
            return None

    def TypeDate(data):
        try:
            return data
        except:
            return None
    
    def TypeDatetime(data):
        try:
            return data
        except:
            return None

安全性过滤内容也可同时写入其中

同时修改add_book

C:\Code\BookManagement\templates\management\add_book.html

def add_book(request):
    if request.user.is_authenticated:
        if request.method == "POST":
            try:
                name = cleandata.TypeChar(request.POST.get('name', ''))
                author = cleandata.TypeChar(request.POST.get('author', ''))
                price = cleandata.TypeFloat(request.POST.get('price', ''))
                publish_date = cleandata.TypeDate(request.POST.get('publish_date', ''))
                cateory = cleandata.TypeChar(request.POST.get('cateory', ''))
                create_datetime = cleandata.TypeDatetime(request.POST.get('create_datetime', ''))
                new_book = models.Book (
                    name = name,
                    author = author,
                    price = price,
                    publish_date = publish_date,
                    cateory = cateory,
                    create_datetime = create_datetime,
                )
                new_book.save()
                state='success'
            except:
                return redirect('/error/')
            return redirect('/book_list/')
    return render(request,"management/add_book.html")
添加error页面

发现还需要error页面,添加error页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('change_password/', views.change_password, name='change_password'),
    path('add_book/', views.add_book, name='add_book'),
    path('book_list/', views.book_list, name='book_list'),
    path('error/', views.error, name='error'),  # 添加error页面
]

C:\Code\BookManagement\management\views.py

def error(request):
    return render(request,"error.html")

C:\Code\BookManagement\templates\error.html

{% extends "management/navbar.html" %}

{% block title %}404{% endblock %}

{% block content %}
    <header class="jumbotron subhead" id="header-base">
        <div class="container">
            <h1 style="text-align: center;line-height:500px">给你一个错误自己领会</h1>
        </div>
    </header>
{% endblock %}

在这里插入图片描述

添加图书页面

继续添加图书

在这里插入图片描述
发现类型应为选择框,根据https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E5%9B%BE%E4%B9%A6%E9%A6%86%E5%9B%BE%E4%B9%A6%E5%88%86%E7%B1%BB%E6%B3%95/1919634将图书分类设为A-Z类

添加图书分类页面

添加图书分类页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('change_password/', views.change_password, name='change_password'),
    path('add_book/', views.add_book, name='add_book'),
    path('book_list/', views.book_list, name='book_list'),
    path('error/', views.error, name='error'),
    path('add_category/', views.add_category, name='add_category'),  # 添加分类页面
    path('category_list/', views.category_list, name='category_list'),  # 添加分类列表页面
]

C:\Code\BookManagement\management\views.py

def add_category(request):
    return render(request,"management/add_category.html")

def category_list(request):
    return render(request,"management/category_list.html")

C:\Code\BookManagement\templates\management\add_category.html

{% extends "management/navbar.html" %}

{% block title %}添加书籍分类{% endblock %}

{% block content %}
<div class="container" style="height: 100px;"></div>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <form method="POST" role="form" class="form-horizontal">
                {% csrf_token %}
                <h1 class="form-signin-heading text-center">添加书籍分类</h1>
                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_parent_category" class="control-label">父类:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_parent_category" name="parent_category" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_category" class="control-label">分类:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_category" required name="category" autocomplete="no" autofocus>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                    </div>
                    <div class="col-md-9">
                        <button class="btn btn btn-primary btn-block" type="submit">提交</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
{% endblock %}

C:\Code\BookManagement\templates\management\category_list.html

{% extends "management/navbar.html" %}

{% block title %}书籍分类列表{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-10 col-md-offset-1">
                <div class="list-group col-md-10">
                    <a href="/category_list/" class="list-group-item" id="id_category_all" style="text-align:center">全部分类</a>
                </div>
                <div class="list-group col-md-2">
                    <a href="/add_category/" class="list-group-item" id="id_category_all" style="text-align:center">添加分类</a>
                </div>
            </div>
            <div class ="col-md-10 col-md-offset-1">
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>父类</th>
                            <th>分类</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for category in category_list %}
                            <tr>
                                <th>{{forloop.counter}}</th>
                                <th><a href="#">{{category.parent_category}}</a></th>
                                <th>{{category.category}}</th>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}

C:\Code\BookManagement\templates\management\navbar.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{% block title%}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
	  <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	  <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="/index/" class="navbar-brand">Library</a>
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage">
                        <a href="/index/">主页</a>
                    </li>
                    <li id="book_list">
                        <a href="/book_list/">书籍列表</a>
                    </li>
                    <li id="category_list">
                        <a href="/category_list/">书籍分类列表</a>
                    </li>
                    
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    {% if user %}
                        <li><a href="/change_password/">{{user}}</a></li>
                        <li><a href="/logout/">退出</a></li>
                    {% else %}
                        <li><a href="/sign_up/">注册</a></li>
                        <li><a href="/login/">登录</a></li>
                    {% endif %}
                </ul>
            </div>
    </nav>
{% block content %}
{% endblock %}
</body>

</html>

在这里插入图片描述
在这里插入图片描述

添加Category数据表

C:\Code\BookManagement\management\models.py

class Category(models.Model):
    parent_category = models.CharField(max_length=32, null=True, blank=True, verbose_name="父类")
    category = models.CharField(
        max_length=32, verbose_name='分类'
    )

要创建表的时候发现前面的category全部写错成了cateory,将涉及到的所有代码中的cateory全部替换为category

python manage.py makemigrations
python manage.py migrate
python manage.py runserver
PS C:\Code\BookManagement> python manage.py makemigrations
Migrations for 'management':
  management\migrations\0002_auto_20220503_1102.py
    - Create model Category
    - Remove field cateory from book
    - Add field category to book
PS C:\Code\BookManagement> python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, management, sessions
Running migrations:
  Applying management.0002_auto_20220503_1102... OK

C:\Code\BookManagement\management\views.py

def add_category(request):
    if request.user.is_authenticated:
        if request.method == "POST":
            try:
                parent_category = cleandata.TypeChar(request.POST.get('parent_category', ''))
                category = cleandata.TypeChar(request.POST.get('category',''))
                new_category = models.Category (
                    parent_category = parent_category,
                    category = category,
                )
                new_category.save()
                state='success'
            except:
                return redirect('/error/')
            return redirect('/category_list/')
    return render(request,"management/add_category.html")

def category_list(request):
    if request.user.is_authenticated:
        if request.method == "GET":
            category_list = models.Category.objects.all().only('parent_category','category')
            content={
                'category_list':category_list,
            }
            print(content)
            return render(request,"management/category_list.html",content)
    return render(request,"management/category_list.html")

根据https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E5%9B%BE%E4%B9%A6%E9%A6%86%E5%9B%BE%E4%B9%A6%E5%88%86%E7%B1%BB%E6%B3%95/1919634将图书分类设为A-Z类,在add_category中添加分类

在这里插入图片描述在这里插入图片描述

在添加图书的位置类型需要根据书籍分类列表中进行选择

在这里插入图片描述

修改添加图书页面

修改add_book页面前端和后端

C:\Code\BookManagement\templates\management\add_book.html

{% extends "management/navbar.html" %}

{% block title %}添加书籍信息{% endblock %}

{% block content %}
<div class="container" style="height: 100px;"></div>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <form method="POST" role="form" class="form-horizontal">
                {% csrf_token %}
                <h1 class="form-signin-heading text-center">添加图书</h1>
                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_name" class="control-label">书名:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_name" required name="name" autocomplete="no" autofocus>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_author" class="control-label">作者:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_author" required name="author" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_category" class="control-label">类型:</label>
                    </div>
                    <div class="col-md-9">
                        <select class="form-control" id="id_category" required name="category">  <!-- 将原有的input更改为select -->
                            <option value=""></option>
                            {% for categoryselection in category_list %}  <!-- 从Category数据表中抽取category数据作为选择项 -->
                                <option value="{{categoryselection.category}}" {% ifequal categoryselection.category category %} selected {% endifequal %} >{{categoryselection.category}}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_price" class="control-label">价格:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="number" step="0.01" min="0" maxlength="200" class="form-control" id="id_price" required name="price" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_pubdate" class="control-label">出版日期:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="date" class="form-control" id="id_pubdate" required name="publish_date" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                    </div>
                    <div class="col-md-9">
                        <button class="btn btn btn-primary btn-block" type="submit">提交</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
{% endblock %}

增加GET方法时return的参数

C:\Code\BookManagement\management\views.py

def add_book(request):
    if request.user.is_authenticated:
        if request.method == "GET":  # 增加GET方法
            category_list = models.Category.objects.all().only('category')
            content = {
                'category_list':category_list,  # 在content中添加category_list
            }
            return render(request,"management/add_book.html",content)  # 增加返回content
        if request.method == "POST":
            try:
                name = cleandata.TypeChar(request.POST.get('name', ''))
                author = cleandata.TypeChar(request.POST.get('author', ''))
                price = cleandata.TypeFloat(request.POST.get('price', ''))
                publish_date = cleandata.TypeDate(request.POST.get('publish_date', ''))
                cateory = cleandata.TypeChar(request.POST.get('cateory', ''))
                create_datetime = cleandata.TypeDatetime(request.POST.get('create_datetime', ''))
                new_book = models.Book (
                    name = name,
                    author = author,
                    price = price,
                    publish_date = publish_date,
                    cateory = cateory,
                    create_datetime = create_datetime,
                )
                new_book.save()
                state='success'
            except:
                return redirect('/error/')
            return redirect('/book_list/')
    return render(request,"management/add_book.html")

修改input为select,分类则变为可选项

在这里插入图片描述

添加前端与后端的实时交互JQuery AJAX

在添加图书位置若添加失败无任何提示信息,使用前端校验固然可以提示,但校验仍然需要以后端为准,添加前端与后端的实时交互

下载JQuery AJAX保持至BookManagement-management-static-jquery目录下

http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.12.4.min.js

修改navbar页面,添加JQuery AJAX和javascript块

C:\Code\BookManagement\templates\management\navbar.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{% block title%}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
	  <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	  <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="/index/" class="navbar-brand">Library</a>
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage">
                        <a href="/index/">主页</a>
                    </li>
                    <li id="book_list">
                        <a href="/book_list/">书籍列表</a>
                    </li>
                    <li id="category_list">
                        <a href="/category_list/">书籍分类列表</a>
                    </li>
                    
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    {% if user %}
                        <li><a href="/change_password/">{{user}}</a></li>
                        <li><a href="/logout/">退出</a></li>
                    {% else %}
                        <li><a href="/sign_up/">注册</a></li>
                        <li><a href="/login/">登录</a></li>
                    {% endif %}
                </ul>
            </div>
    </nav>
{% block content %}
{% endblock %}
<script src="{% static 'jquery/jquery-1.12.4.min.js' %}"></script>
{% block javascript %}
{% endblock %}
</body>
</html>
修改添加图书页面

修改add_book页面,添加javascript

C:\Code\BookManagement\templates\management\add_book.html

{% extends "management/navbar.html" %}

{% block title %}添加书籍信息{% endblock %}

{% block content %}
<div class="container" style="height: 100px;"></div>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div role="form" class="form-horizontal">  <!-- 将原有的form表单修订为div -->
                {% csrf_token %}
                <h1 class="form-signin-heading text-center">添加图书</h1>
                <div style="height: 60px;">  <!-- 添加div位置和高度 -->
                    <div class="alert alert-success" role="alert" id="id_alert_success" style="text-align: center;" hidden>  <!-- 添加成功时提示绿色提示框,默认隐藏 -->
                        添加成功
                    </div>
                    <div class="alert alert-danger" role="alert" id="id_alert_danger" style="text-align: center;" hidden>  <!-- 添加失败时提示红色提示框,默认隐藏 -->
                        添加失败
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_name" class="control-label">书名:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_name" required name="name" autocomplete="no" autofocus>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_author" class="control-label">作者:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" maxlength="200" class="form-control" id="id_author" required name="author" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_category" class="control-label">类型:</label>
                    </div>
                    <div class="col-md-9">
                        <select class="form-control" id="id_category" required name="category">
                            <option value=""></option>
                            {% for categoryselection in category_list %}
                                <option value="{{categoryselection.category}}" {% ifequal categoryselection.category category %} selected {% endifequal %} >{{categoryselection.category}}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_price" class="control-label">价格:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="number" step="0.01" min="0" maxlength="200" class="form-control" id="id_price" required name="price" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                        <label for="id_pubdate" class="control-label">出版日期:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="date" class="form-control" id="id_publish_date" required name="publish_date" autocomplete="no">
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-md-3">
                    </div>
                    <div class="col-md-9">
                        <button class="btn btn btn-primary btn-block" type="submit" id="id_submit">提交</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block javascript %}
<script>
    $('#id_submit').click(function () {
		var csrf = $('input[name="csrfmiddlewaretoken"]').val();
        $.ajax({
            url:'',
            type:'post',
            data:{'name':$('#id_name').val(),
                  'author':$('#id_author').val(),
                  'category':$('#id_category').val(),
                  'price':$('#id_price').val(),
                  'publish_date':$('#id_publish_date').val(),
                  'csrfmiddlewaretoken': csrf,
                },
            success:function(state) {
                if (state == '添加成功') {
                    $('#id_alert_success').slideDown(500);
                    $('#id_alert_success').slideUp(1200);
                    $('#id_alert_success').text(state);
                }
                else {
                    $('#id_alert_danger').slideDown(500);
                    $('#id_alert_danger').slideUp(1200);
                    $('#id_alert_danger').text(state);
                }
            }
        })
    })
</script>
{% endblock %}

C:\Code\BookManagement\management\views.py

from django.http import HttpResponse

def add_book(request):
    if request.user.is_authenticated:
        if request.method == "GET":
            category_list = models.Category.objects.all().only('category')
            content = {
                'category_list':category_list,
            }
            return render(request,"management/add_book.html",content)
        if request.method == "POST":
            try:
                name = cleandata.TypeChar(request.POST.get('name', ''))
                author = cleandata.TypeChar(request.POST.get('author', ''))
                price = cleandata.TypeFloat(request.POST.get('price', ''))
                publish_date = cleandata.TypeDate(request.POST.get('publish_date', ''))
                category = cleandata.TypeChar(request.POST.get('category', ''))
                create_datetime = cleandata.TypeDatetime(request.POST.get('create_datetime', ''))
                if name == "":
                    state='书名都不填的么'
                elif author == "":
                    state='作者都不填的么'
                elif price == "":
                    state='价格都不填的么'
                elif publish_date == "":
                    state='出版日期都不填的么'
                elif category == "":
                    state='类型都不选的么'
                else:
                    if models.Book.objects.filter(name=name,author=author):
                        state='已经添加过这本书籍了'
                    else:
                        models.Book.objects.create(
                            name = name,
                            author = author,
                            price = price,
                            publish_date = publish_date,
                            category = category,
                            create_datetime = create_datetime,
                        )
                        state='添加成功'
            except:
                state='添加失败'
            finally:
                return HttpResponse(state)
    return render(request,"management/add_book.html")

在这里插入图片描述在这里插入图片描述

在book_list页面中点击书名无法跳转到详情页面

在这里插入图片描述

修改添加书籍详情页面

添加书籍详情页面

C:\Code\BookManagement\management\urls.py

from django.urls import URLPattern, path
from management import views

urlpatterns = [
    path('', views.index, name='homepage'),
    path('index/', views.index, name='homepage'),
    path('sign_up/', views.sign_up, name='sign_up'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('change_password/', views.change_password, name='change_password'),
    path('add_book/', views.add_book, name='add_book'),
    path('book_list/', views.book_list, name='book_list'),
    path('error/', views.error, name='error'),
    path('add_category/', views.add_category, name='add_category'),
    path('category_list/', views.category_list, name='category_list'),
    path('book_detail/', views.book_detail, name='book_detail'),
]

C:\Code\BookManagement\management\views.py

def book_detail(request):
    return render(request,"management/book_detail.html")

C:\Code\BookManagement\templates\management\book_detail.html

{% extends "management/navbar.html" %}

{% block title %}书籍详情{% endblock %}

{% block content %}
<div class="container" style="height: 100px;"></div>
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div role="form" class="form-horizontal">
                {% csrf_token %}
                <h1 class="form-signin-heading text-center">书籍详情</h1>
                <div class="form-group">
                    <div class="col-md-10">
                        <label for="id_name" class="control-label">{{book.name}}</label>
                    </div>
                </div>
                
                <div class="form-group">
                    <div class="col-md-10">
                        <label for="id_name" class="control-label">{{book.author}}</label>
                    </div>
                </div>
                
                <div class="form-group">
                    <div class="col-md-10">
                        <label for="id_name" class="control-label">{{book.category}}</label>
                    </div>
                </div>
                
                <div class="form-group">
                    <div class="col-md-10">
                        <label for="id_name" class="control-label">{{book.price}}</label>
                    </div>
                </div>
                
                <div class="form-group">
                    <div class="col-md-10">
                        <label for="id_name" class="control-label">{{book.publish_date}}</label>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

在这里插入图片描述

修改定位书籍信息

修改book_list在跳转至book_detail时带上书籍唯一id信息

C:\Code\BookManagement\templates\management\book_list.html

{% extends "management/navbar.html" %}

{% block title %}登录{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-10 col-md-offset-1">
                <div class="list-group col-md-10">
                    <a href="/book_list/" class="list-group-item" id="id_category_all" style="text-align:center">全部图书</a>
                </div>
                <div class="list-group col-md-2">
                    <a href="/add_book/" class="list-group-item" id="id_category_all" style="text-align:center">添加书籍</a>
                </div>
            </div>
            <div class ="col-md-10 col-md-offset-1">
                <table class="table table-hover">
                    {% csrf_token %}
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>书名</th>
                            <th>作者</th>
                            <th>出版日期</th>
                            <th>定价</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for book in book_list %}
                            <tr>
                                <th>{{forloop.counter}}</th>
                                <th><a href="/book_detail?id={{book.id}}">{{book.name}}</a></th>  <!-- 添加book.id跳转至书籍详情 -->
                                <th>{{book.author}}</th>
                                <th>{{book.publish_date}}</th>
                                <th>{{book.price}}</th>
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}

C:\Code\BookManagement\management\views.py

def book_list(request):
    if request.user.is_authenticated:
        if request.method == "GET":
            book_list = models.Book.objects.all().only('id','name','author','publish_date','price')  # 添加返回id
            content={
                'book_list':book_list,
            }
            return render(request,"management/book_list.html",content)
    return render(request,"management/book_list.html")

C:\Code\BookManagement\management\views.py

def book_detail(request):
    if request.user.is_authenticated:
        if request.method == "GET":
            id = cleandata.TypeNum(request.GET.get('id', ''))
            if id != '' and id != 0:
                book = models.Book.objects.get(id=id)
                content = {
                    'book':book,
                }
                return render(request,"management/book_detail.html",content)
    return render(request,"management/book_detail.html")

在这里插入图片描述

涉及POST请求的还有注册、登录、书籍分类,逐一添加提示信息

C:\Code\BookManagement\templates\management\sign_up.html

{% extends "management/navbar.html" %}

{% block title %}注册{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3 col-sm-10 col-sm-offset-1">
                <div role="form" class="form-horizontal">
                    {% csrf_token %}
                    <h1 class="form-signin-heading text-center">请注册</h1>
                    <div style="height: 60px;">
                        <div class="alert alert-success" role="alert" id="id_alert_success" style="text-align: center;" hidden>
                            添加成功
                        </div>
                        <div class="alert alert-danger" role="alert" id="id_alert_danger" style="text-align: center;" hidden>
                            添加失败
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_username" class="col-md-3 control-label">用户名:</label>
                        <div class="col-md-9">
                            <input type="text" class="form-control" id="id_username" required name="username" autofocus>
                            <span class="help-block">用于登录,可以包括大小写字母和下划线。</span>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_password" class="col-md-3 control-label">口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_password" required name="password">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_repassword" class="col-md-3 control-label">重复口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_repassword" required name="repassword">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_email" class="col-md-3 control-label">电子邮件:</label>
                        <div class="col-md-9">
                            <input type="email" class="form-control" id="id_email" required name="email">
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-9 col-md-offset-3">
                            <button class="btn btn btn-primary btn-block" type="submit" id="id_submit">注册</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block javascript %}
<script>
    $('#id_submit').click(function () {
		var csrf = $('input[name="csrfmiddlewaretoken"]').val();
        $.ajax({
            url:'',
            type:'post',
            data:{
                'username':$('#id_username').val(),
                'password':$('#id_password').val(),
                'repassword':$('#id_repassword').val(),
                'email':$('#id_email').val(),
                'csrfmiddlewaretoken': csrf,
            },
            success:function(state) {
                if (state == '注册成功') {
                    $('#id_alert_success').slideDown(500);
                    $('#id_alert_success').slideUp(1200);
                    $('#id_alert_success').text(state);
                    window.location.replace("/index/");
                }
                else {
                    $('#id_alert_danger').slideDown(500);
                    $('#id_alert_danger').slideUp(1200);
                    $('#id_alert_danger').text(state);
                }
            }
        })
    })
</script>
{% endblock %}

C:\Code\BookManagement\management\views.py

def sign_up(request):
    if request.method == "POST":
        try:
            username = request.POST.get('username', '')
            password = request.POST.get('password', '')
            repassword = request.POST.get('repassword', '')
            email = request.POST.get('email', '')
            if password == '' or repassword == '':
                state = '口令都不填的么'
            elif password != repassword:
                state = '你这两遍口令填的不同啊'
            else:
                if User.objects.filter(username=username):
                    state = '换个用户名,这个已经被占用了'
                else:
                    new_user = User.objects.create_user(
                        username=username, password=password, email=email)
                    new_user.save()
                    state = '注册成功'
                    return redirect("/index/")
        except:
            state = '注册失败'
        finally:
            return HttpResponse(state)
    return render(request, "management/sign_up.html")

在这里插入图片描述在这里插入图片描述

C:\Code\BookManagement\templates\management\login.html

{% extends "management/navbar.html" %}

{% block title %}登录{% endblock %}

{% block content %}
    <div class="container" style="height: 100px;"></div>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3 col-sm-10 col-sm-offset-1">
                <div role="form" class="form-horizontal">
                    {% csrf_token %}
                    <h1 class="form-signin-heading text-center">请登录</h1>
                    <div style="height: 60px;">
                        <div class="alert alert-success" role="alert" id="id_alert_success" style="text-align: center;" hidden>
                            添加成功
                        </div>
                        <div class="alert alert-danger" role="alert" id="id_alert_danger" style="text-align: center;" hidden>
                            添加失败
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_username" class="col-md-3 control-label">用户名:</label>
                        <div class="col-md-9">
                            <input type="text" class="form-control" id="id_username" required name="username" autofocus>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="id_password" class="col-md-3 control-label">口令:</label>
                        <div class="col-md-9">
                            <input type="password" class="form-control" id="id_password" required name="password">
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-9 col-md-offset-3">
                            <button class="btn btn btn-primary btn-block" type="submit" id="id_submit">登录</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block javascript %}
<script>
    $('#id_submit').click(function () {
		var csrf = $('input[name="csrfmiddlewaretoken"]').val();
        $.ajax({
            url:'',
            type:'post',
            data:{
                'username':$('#id_username').val(),
                'password':$('#id_password').val(),
                'csrfmiddlewaretoken': csrf,
            },
            success:function(state) {
                if (state == '登录成功') {
                    $('#id_alert_success').slideDown(500);
                    $('#id_alert_success').slideUp(1200);
                    $('#id_alert_success').text(state);
                    window.location.replace("/index/");
                }
                else {
                    $('#id_alert_danger').slideDown(500);
                    $('#id_alert_danger').slideUp(1200);
                    $('#id_alert_danger').text(state);
                }
            }
        })
    })
</script>
{% endblock %}

C:\Code\BookManagement\management\views.py

def login(request):
    if request.method == "POST":
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if username and password:
            user = auth.authenticate(username=username, password=password)
            if user is not None:
                auth.login(request, user)
                state = '登录成功'
                return HttpResponse(state)
            else:
                state = '用户不存在或口令错误'
                return HttpResponse(state)
    return render(request, "management/login.html")

在这里插入图片描述
在这里插入图片描述

修改用户未登录时前端显示错误问题

未登录时用户位置显示AnomymousUser……

在这里插入图片描述

C:\Code\BookManagement\templates\management\navbar.html

{% load static %}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>{% block title%}{% endblock %}</title>
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
	  <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
	  <script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
</head>

<body>
    <nav class="navbar navbar-inverse navbar-fixed-top" role="navigatioin">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#navbar-collapse-basepage">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a href="/index/" class="navbar-brand">Library</a>
            </div>
            <div class="collapse navbar-collapse" id="navbar-collapse-basepage">
                <ul class="nav navbar-nav">
                    <li id="homepage">
                        <a href="/index/">主页</a>
                    </li>
                    <li id="book_list">
                        <a href="/book_list/">书籍列表</a>
                    </li>
                    <li id="category_list">
                        <a href="/category_list/">书籍分类列表</a>
                    </li>
                    
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    {% if username %}  # 将原有的变量名user修订为uesrname
                        <li><a href="/change_password/">{{username}}</a></li>
                        <li><a href="/logout/">退出</a></li>
                    {% else %}
                        <li><a href="/sign_up/">注册</a></li>
                        <li><a href="/login/">登录</a></li>
                    {% endif %}
                </ul>
            </div>
    </nav>
{% block content %}
{% endblock %}
<script src="{% static 'jquery/jquery-1.12.4.min.js' %}"></script>
{% block javascript %}
{% endblock %}
</body>
</html>

C:\Code\BookManagement\management\views.py

def index(request):
    if request.user.is_authenticated:
        username = request.user  # 将原有的变量名user修订为uesrname
        content={
            'username':username,
        }
        return render(request, "management/index.html",content)
    return render(request, "management/index.html")
重新选择皮肤

页面微丑,选个合适的皮肤

目前最新的是Bootstrap5,下载Bootstrap5

替换C:\Code\BookManagement\management\static中对应的js、css

选择examples中的样例,选择样例
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全面修订样式和前端体验

修订样式并稍微修订前端体验,当前代码位于《Django开发从入门到实践》学习笔记(代码)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

部署上线

操作系统版本:CentOS Linux release 8.5.2111
Docker版本:Docker version 20.10.12, build e91ed57
Docker容器版本:Ubuntu 22.04 LTS

安装

# 获取ubuntu镜像
sudo docker pull ubuntu
# 创建ubuntu容器并映射端口8888/8000命令为BookManagement
sudo docker run --name BookManagement -p8888:8888 -p8000:8000 -it -id ubuntu /bin/bash
# 进入BookManagement容器
sudo docker exec -it BookManagement /bin/bash
# apt-get更新
apt-get update
# 安装python3、pip3、nginx
apt-get -y install python-dev-is-python3 python3-pip nginx
# 安装uwsgi、django3
pip install uwsgi django==3.0.6

配置

修改/etc/BookManagement/BookManagement/settings.py文件

/etc/BookManagement/BookManagement/settings.py

# 上线后不能为调试模式,关闭调试模式
DEBUG = False
# 未配置时默认本地访问,上线后需要开放远程访问,可配置为具体的目标IP地址或开放远程访问
ALLOWED_HOSTS = ['*']
# 原有配置
STATIC_URL = '/static/'
# 添加BASE_DIR配置以指向STATIC_URL路径
STATIC_ROOT = os.path.join(BASE_DIR,"/etc/BookManagement/management/")
# 将Django项目从本地复制到服务器宿主机
scp -r C:\Code\BookManagement root@0.0.0.0:/etc/
# 将Django项目从服务器宿主机复制到Docker容器内
sudo docker cp /etc/BookManagement BookManagement:/etc/
# 进入BookManagement项目
cd /etc/BookManagement
# 将配置的静态文件收集到STATIC_ROOT中
python manage.py collectstatic

若使用Django+uwsgi访问,可使用http路由访问http://0.0.0.0:8888,映射的8888端口用于访问http路由方式部署的uwsgi,确定使用http路由方式访问则此时的状态后台运行Ctrl+Z即可

# --chdir配置项目绝对路径、--wsgi-file配置wsgi.py依据项目绝对路径的相对路径、--static-map配置/static/绝对路径
uwsgi --http-socket :8888 --chdir /etc/BookManagement/ --wsgi-file BookManagement/wsgi.py --static-map=/static/=/etc/BookManagement/management/static --master --process 4 --workers 4

若使用Django+uwsgi+nginx访问,可使用socket路由访问nginx端口,映射的8000端口用于访问socket路由方式部署的uwsgi访问后的nginx反向代理,上述访问需要Ctrl+C中断或ps -ef | grep uwsgi查看id后中断

# --chdir配置项目绝对路径、--wsgi-file配置wsgi.py依据项目绝对路径的相对路径、--static-map配置/static/绝对路径
uwsgi --socket :8888 --chdir /etc/BookManagement/ --wsgi-file BookManagement/wsgi.py --static-map=/static/=/etc/BookManagement/management/static --master --process 4 --workers 4
# 配置nginx.conf
cat >/etc/nginx/nginx.conf
# 配置nginx启动用户
user root;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 768;
    # multi_accept on;
}

http {
    # 配置文件类型值
    include mime.types;  # 包含静态文件解析方式
    default_type  application/octet-stream;
    server {
        listen     8887;  # 配置nginx监听端口
        server_name  127.0.0.1;  # 配置服务器地址,若为本地则为127.0.0.1或localhost
        charset UTF-8;
        access_log   /var/log/nginx/access.log;  # 配置访问日志地址
        error_log    /var/log/nginx/error.log;  # 配置错误日志地址
        location / {
            uwsgi_pass 127.0.0.1:8888;  # 传递每一个请求给绑定到8888端口并使用uwsgi协议的服务器
            include /etc/nginx/uwsgi_params;  # 包含uwsgi_params
        }
        location /static {  # 配置/static中css、js路径
            expires 30d;
            autoindex on;
            add_header Cache-Control private;
            alias /etc/BookManagement/management;  # /static的上层绝对路径
        }
    }
}

启动nginx服务

service nginx restart

访问

访问http://0.0.0.0:8000,实际IP地址为服务器宿主机的IP地址

在这里插入图片描述

参考链接:
https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/WSGIquickstart.html
https://blog.csdn.net/weixin_42134789/article/details/115713572

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Django是一个开源的Web应用框架,使用Python语言开发。它简化了Web应用开发的过程,提供了许多便捷的功能和模块,使得开发人员能够更快速、高效地开发出符合需求的Web应用。 从入门实践学习Django开发需要掌握以下几个方面: 1. 环境搭建:首先需要安装PythonDjango开发环境。可以通过pip命令安装Django,并搭建一个虚拟环境来管理项目。 2. 项目创建:使用Django的命令行工具创建一个新的Django项目。这将生成项目的基本结构和文件,包括配置文件和应用程序。 3. 数据库配置:在Django中使用数据库,需要在配置文件中设置数据库连接信息。可以选择常用的关系型数据库,如MySQL或SQLite。 4. URL配置:Django使用URL映射来处理用户的请求。在项目的URL配置文件中,将URL和对应的处理视图函数进行绑定。 5. 视图函数:Django的视图函数负责处理请求,并返回相应的响应。可以在视图函数中编写逻辑代码和业务逻辑。 6. 模板引擎:Django内置了强大的模板引擎,用于生成动态的HTML页面。可以在模板中使用Django提供的模板语法,包括变量、标签和过滤器等。 7. 表单处理:Django提供了方便的表单处理功能,可以用于处理用户输入的数据。可以根据需求创建自定义的表单类,并进行表单验证和处理。 8. 中间件:Django的中间件是位于请求和响应之间的处理组件,可以在请求处理过程中进行一些自定义操作,如身份验证、请求记录和缓存等。 9. 数据库操作:Django提供了ORM(对象关系映射)工具,可以通过Python代码进行数据库操作,而不用直接编写SQL语句。 10. 部署上线:当开发完成后,需要将项目部署到生产环境中。可以选择合适的服务器和Web服务器,如Nginx和Apache,进行部署和配置。 通过学习以上内容,我们可以掌握Django开发流程和常用模块的使用。通过实际的项目开发,可以深入理解Django的各个方面,并逐渐掌握高级的开发技术和扩展功能。 ### 回答2: Django是一个开源的Web应用框架,使用Python语言编写。它通过提供一组强大的工具和接口,帮助开发者快速构建高效、可扩展的Web应用程序。 从入门实践,首先我们需要掌握Python语言的基础知识,了解Python的语法和常用库函数等。接着,我们可以开始学习Django框架的使用。 在学习过程中,我们需要熟悉Django的核心概念和组件,例如模型(Model)、视图(View)和模板(Template)等。模型用于定义数据结构,视图处理用户请求并返回响应,模板用于渲染动态页面。掌握这些基本概念后,我们可以开始进行实践实践中,我们可以开发一个典型的Web应用,如博客网站。首先,我们需要定义博客的数据结构,例如文章、作者和评论等。然后,我们可以创建相应的模型,并通过Django提供的数据库迁移工具生成数据库表格。 接着,我们可以编写视图函数来处理用户请求。例如,当用户访问博客首页时,我们可以查询数据库获取最新的文章列表,并通过模板渲染页面后返回给用户。当用户点击某篇文章时,我们可以根据文章的ID查询数据库,获取文章的详细内容并显示在页面上。 在开发过程中,我们可能还需要创建用户注册、登录和退出等功能。这时,我们可以使用Django提供的用户认证和管理模块,轻松实现这些功能。 最后,我们还可以通过Django的后台管理功能方便地管理数据。Django提供了一个自动生成的管理界面,我们可以通过简单的配置即可实现对数据的增删改查操作,而无需编写额外的代码。 总之,通过从入门实践学习实践,我们可以掌握Django开发技巧和典型模块的使用,从而能够快速开发出高效、可扩展的Python Django Web应用程序。 ### 回答3: Django是一个开放源代码的Python Web应用程序框架,它通过提供一个简单方便的开发环境,帮助开发人员快速构建高质量的Web应用程序。 从入门实践,首先需要掌握一些基本的Python编程知识。Python具有简单易学的语法和丰富的标准库,对于初学者来说,上手较为容易。接下来,了解Django框架的设计理念和基本概念是必不可少的。Django采用了MVC(模型-视图-控制器)的架构模式,其中模型负责数据处理和存储,视图负责处理用户请求和渲染HTML模板,控制器负责协调模型和视图之间的交互。 在开发过程中,使用Django提供的典型模块是非常常见的。其中最重要的模块之一是ORM(对象关系映射),它能够将数据库中的数据映射为Python对象,并提供了一种直观的方式来操作数据库。ORM能够简化数据库操作,并提供了一致的API,使得开发更加高效和可维护。另外,Django的表单模块也是非常重要的,它能够帮助我们在Web应用程序中处理用户输入,并进行验证和数据清洗。表单模块提供了丰富的字段类型和验证器,使得表单开发更加简单和高效。 除了ORM和表单模块,Django还提供了许多其他有用的模块,例如身份认证和授权模块、缓存模块、国际化和本地化模块等等。这些模块能够帮助我们快速构建功能强大的Web应用程序。 在实践中,我们可以通过参考Django官方文档、教程和案例来学习开发技巧和最佳实践。同时,参与开源项目和与其他开发者交流也是非常重要的,可以提升自己的开发能力和不断学习新技术。 总之,通过学习Python编程基础、掌握Django框架的基本概念和典型模块,以及不断实践和参与开发社区,我们可以逐步提升自己的Django开发技能,从而构建出高质量的Web应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值