Python Django框架下将MySQL数据库的内容在网页上动态展示(修订版-2021-05-17)
需求:将数据库中的一个库内的单表数据展示在网页首页,该表有id列,名字列,学号列三个列,并有简单的逻辑:能修改单行内的名字和学号,能删除任意的行,修改和删除后仍然自动跳转到展示页。没有分页,权限管理等功能,仅仅是个简单的展示、
删除后:
修改中:
============================================================================
下面就开始讲解:
一,
项目的建立
首先,新建项目,项目名称为sims。运行命令:Python manage.py startproject sims
这里需要说明一下环境,使用的是Python3.8,pycharm专业版,使用Windows,所建立的项目,Django的版本等等见下面(Django使用的是1.11.27,我安装了一个jupyter):
argon2-cffi==20.1.0 async-generator==1.10 attrs==21.2.0 backcall==0.2.0 bleach==3.3.0 cffi==1.14.5 colorama==0.4.4 decorator==5.0.9 defusedxml==0.7.1 Django==1.11.27 entrypoints==0.3 ipykernel==5.5.5 ipython==7.23.1 ipython-genutils==0.2.0 ipywidgets==7.6.3 jedi==0.18.0 Jinja2==3.0.0 jsonschema==3.2.0 jupyter==1.0.0 jupyter-client==6.2.0 jupyter-console==6.4.0 jupyter-core==4.7.1 jupyterlab-pygments==0.1.2 jupyterlab-widgets==1.0.0 MarkupSafe==2.0.0 matplotlib-inline==0.1.2 mistune==0.8.4 mysqlclient==1.4.6 nbclient==0.5.3 nbconvert==6.0.7 nbformat==5.1.3 nest-asyncio==1.5.1 notebook==6.3.0 packaging==20.9 pandocfilters==1.4.3 parso==0.8.2 pickleshare==0.7.5 prometheus-client==0.10.1 prompt-toolkit==3.0.18 pycparser==2.20 pyftpdlib==1.5.6 Pygments==2.9.0 pyparsing==2.4.7 pyrsistent==0.17.3 python-dateutil==2.8.1 pytz==2021.1 pywin32==300 pywinpty==0.5.7 pyzmq==22.0.3 qtconsole==5.1.0 QtPy==1.9.0 Send2Trash==1.5.0 six==1.16.0 terminado==0.9.5 testpath==0.4.4 tornado==6.1 traitlets==5.0.5 wcwidth==0.2.5 webencodings==0.5.1 widgetsnbextension==3.5.1
数据库使用的是mariadb-5.5,安装方式为centos7.2下的RPM包安装 方式,这里需要注意,因为是RPM包安装,因此,需要对mariadb做适当的修改,主要是字符集的设置,这个就不在此讨论了,因为这些是基本的运维工作。
整体项目使用的是mariadb驱动,具体版本为mariadb-java-client-2.6.0.jar。
在项目目录下的settings.py文件中注册app。app名称为test(我用user,这个APP不能注册,原因未知,很郁闷)。以下为setting的全部内容(不包括注释)
需要修改的地方是:
INSTALLED_APPS
TEMPLATES
DATABASES
这里需要说明一下,DATABASES这一块是使用的是mysql,mariadb和mysql Django认为没有什么太大的区别。
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 = 'k&p=zqkw7(vls^6avyjjv-_ro11e93y#8w-xgp9d1qs$!ejf0w' # 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', 'test', ] 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 = 'sims.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 = 'sims.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { #使用的驱动引擎是mysql 'ENGINE': 'django.db.backends.mysql', #这个name是数据库的库名哦,一会建库的时候可要一致哦 'NAME': 'mysims', 'USER': 'root', 'PASSWORD': '123456', 'HOST': '192.168.88.11', 'PORT': '3306', } } # 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/'
注意,数据库最好先建立,模板文件夹是在工程的下一级目录,右键点击项目名称为sims那个文件夹,新建文件夹,名称为templates。右键点击templates文件夹,再建立一个文件夹,名称为student。以上准备完毕后,运行命令:python manage.py startapp user(注册的哪个名字就写哪个名字)。至此,基本的项目环境准备完毕(Django项目和python所使用的MySQL连接驱动要安装哦,否则,初始化MySQL数据库不会成功)。
============================================================================
运行命令:Python manage.py startapp user
执行完毕后,在项目下会多出一个平级目录并且该目录为前面注册的APP名称,其下有五个文件。整体项目的目录大概是长这样的~~~~
二,
数据库的初始化工作
接下来开始编辑 models.py文件
from django.db import models # Create your models here. class Student(models.Model): student_no = models.CharField(max_length=32,unique=True) student_name = models.CharField(max_length=32) student_city = models.CharField(max_length=32)
这个类名就是将要新建立的表的名称,最终数据中生成的表的名称为app名称_类名,所以请注意这个类名,尽量的有些含义。
执行两个命令:python manage.py makemigrations test
python manage.py migrate test
执行完毕后,数据库中所使用的表将会初始化并生成。当然,表暂时是空的,里面没有数据(这是原始的第一版图,不要写user哦,要写test!!!!!)
此时,我们登录mariadb,可以观察到:
MariaDB [(none)]> use mysims; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [mysims]> show tables; +----------------------------+ | Tables_in_mysims | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | | test_student | +----------------------------+ 11 rows in set (0.00 sec)
很明显的,我们这个数据库自动生成了很多表,其中主要的是test_student 这个表,该表将是我们这个项目所使用的主要表,学生的学号和学生的姓名等都是持久化存储到这个表里的。这个表的名字是APP的名称_models.py这个文件所定义的类。(一定要深刻理解这个数据库中表的名字的由来)
这样的就是成功初始化了。
===========================================================================
三,
配置路由:
test/urls.py文件:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index), url(r'^add/$', views.add), url(r'^edit/$', views.edit), url(r'^delete/$', views.delete), ]
sims/urls.py:
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include('test.urls')), ]
============================================================================
四,
配置视图(逻辑函数都在里面):
test/views.py
from django.shortcuts import render # Create your views here. from django.http import HttpResponse import MySQLdb from django.shortcuts import render, redirect # Create your views here. #学生信息列表处理函数,直接读取数据库的内容,将内容渲染到静态展示页面,算是查这个功能的实现。 def index(request): conn = MySQLdb.connect(host="192.168.88.11", user="root", passwd="123456", db="mysims", charset='utf8') with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: cursor.execute("SELECT id,student_no,student_name,student_city FROM test_student") students = cursor.fetchall() return render(request, 'student/index.html', {'students': students}) # 学生信息新增处理函数,这是增功能函数,注意返回的路由,增加动作完毕后自动跳转到查页面 def add(request): if request.method == 'GET': return render(request, 'student/add.html') else: student_no = request.POST.get('student_no', '') student_name = request.POST.get('student_name', '') student_city = request.POST.get('student_city') conn = MySQLdb.connect(host="192.168.88.11", user="root", passwd="123456", db="mysims", charset='utf8') with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: cursor.execute("INSERT INTO test_student (student_no,student_name,student_city) " "values (%s,%s,%s)", [student_no, student_name,student_city]) conn.commit() return redirect('../') # 学生信息修改处理函数,同上,只是sql语句不一样而已,换成了update语句。 def edit(request): if request.method == 'GET': id = request.GET.get("id") conn = MySQLdb.connect(host="192.168.88.11", user="root", passwd="123456", db="mysims", charset='utf8') with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: cursor.execute("SELECT id,student_no,student_name,student_city FROM test_student where id =%s", [id]) student = cursor.fetchone() return render(request, 'student/edit.html', {'student': student}) else: id = request.POST.get("id") student_no = request.POST.get('student_no', '') student_name = request.POST.get('student_name', '') student_city = request.POST.get('student_city', '') conn = MySQLdb.connect(host="192.168.88.11", user="root", passwd="123456", db="mysims", charset='utf8') with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: cursor.execute("UPDATE test_student set student_no=%s,student_name=%s,student_city=%s where id =%s", [student_no, student_name, student_city, id]) conn.commit() return redirect('../') # 学生信息删除处理函数,同上,SQL语句改变而已。 def delete(request): id = request.GET.get("id") conn = MySQLdb.connect(host="192.168.88.11", user="root", passwd="123456", db="mysims", charset='utf8') with conn.cursor(cursorclass=MySQLdb.cursors.DictCursor) as cursor: cursor.execute("DELETE FROM test_student WHERE id =%s", [id]) conn.commit() return redirect('../') #返回上层url
==============================================================================
五,
前端页面的生成
三个HTML文件:
template/student/.index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学生列表</title> </head> <body> <table border="1px" width="100%" style="border-collapse: collapse;"> <a href="../add">添加学生</a> <tr> <th>编号</th> <th>姓名</th> <th>学号</th> <th>操作</th> </tr> {% for student in students %} <tr> <td align="center">{{ forloop.counter }} </td> <td align="center">{{ student.student_name }} </td> <td align="center">{{ student.student_no }} </td> <td align="center"> <a href="../edit/?id={{ student.id }}"> 编辑 </a> <a href="../delete/?id={{ student.id }}"> 删除 </a> </td> </tr> {% endfor %} </table> </body> </html>
template/student/add.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学生添加</title> <style> form { margin: 20px auto; width: 500px; border: 1px solid #ccc; padding: 20px } </style> </head> <body> <form method="post" action="../add/"> {% csrf_token %} <table> <tr> <th>姓名</th> <td><input name="student_name"></td> </tr> <tr> <th>学号</th> <td><input name="student_no"/></td> </tr> tr> <th>城市</th> <td><input name="student_city"/></td> </tr> <tr> <td colspan="3"> <input type="submit"/> </td> </tr> </table> </form> </body> </html>
template/student/edit.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学生编辑</title> <style> form { margin: 20px auto; width: 500px; border: 1px solid #ccc; padding: 20px } </style> </head> <body> <form method="post" action="../edit/"> {% csrf_token %} <input type="hidden" name="id" value="{{ student.id }}"/> <table> <tr> <th>姓名</th> <td><input name="student_name" value="{{ student.student_name }}"></td></tr> <tr> <th>学号</th> <td><input name="student_no" value="{{ student.student_no }}"/></td> </tr> <tr> <th>城市</th> <td><input name="student_city" value="{{ student.student_city }}"></td></tr><tr> <td colspan="2"> <input type="submit"/> </td> </tr> </table> </form> </body> </html>
因为删除数据后就直接跳转到查看页面了,因此不需要单独编写,只需要前后端数据同步好后,刷新index页面,能在展示页面也就是index.html这看到就可以了。增加和修改功能是另外的逻辑,因此需要单独编写。
六,
这个简单项目的运行
那么,现在就可以运行命令:Python manage.py runserver,
该程序会启动开发服务器,以便使用浏览器来测试你的APP运行。
总结:
严格按照本博客编写这个项目,是一定会写出这些页面的,其中涉及到的知识点比较多,前后端的知识点都有所涉猎,如果,对开发有兴趣,我想,从环境的搭建开始,是一个不错的开始。