怎么用python搭建网站_简明Python开发教程(6):用Django搭建网站

前面已经分享了Python的基础知识和典型应用,那么如何可视化呈现结果并进行交互?

一般用网页形式进行展示,网页展示结果、交互,服务器后台提供数据支持。开发网站又是一个复杂的工作。

幸好Python的Django框架可以让我们非常容易的搭建网站系统,只需要我们学习一点点HTML、CSS、JavaScript等前端知识,了解一下Django的工作原理就可以工作了。

前期我们梳理了工作岗位需要掌握的11大类、327小类技能点,并对27位同事的技能掌握进行摸底调查,分为:没听过、初级、中级、高级四部分;

同时统计近5年的外出培训记录。

目前需要开发一个网站,提供查询功能:

1)按人员查:对比显示该同事的技能掌握情况和培训记录;

2)按技能查询:显示不同基本人员分布情况

1 Django介绍

Django是用Python开发的免费开源web框架。

当初我使用自强学堂完成学习入门,推荐。

首先需要安装相应版本的Django,如1.11。

如果已经安装Anaconda,那么使用conda intsall django。即可完成安装。

一般情况,开发Django应用有以下几步:

1.1 创建一个工程

使用django-admin.py startproject project_name创建一个新工程,然后发现会自动新建一个文件夹,有着一定的模板。

image.png

可以看到目录结构基本如下:

hrinfo/

manage.py

hrifno/

__init__.py

settings.py

urls.py

wsgi.py

urls.py写一些url解析规则,setting.py包含一些全局配置信息,manage.py提供一些管理功能。

如进入工程目录,运行开发环境,测试Django是否工作正常。

image.png

一切正常,打开浏览器,输入127.0.0.1:8000,结果如下,说明Django工作正常。

image.png

1.2 新建一个应用App

进入工程目录后,输入python manage.py startapp hrskill,可以发现新建一个hrskill文件夹,包含若干文件:

image.png

这里最重要的是views.py文件,写网站后台处理逻辑。

1.3 修改配置setting.py文件

打开setting.py文件,增加App名称,如果希望关联数据库,如修改为Mysql

数据库,也可以配置,这里简化处理,这里不配数据库。

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'hrskill', #新增配置

]

1.4 测试应用功能

通过修改urls.py 和 views.py来测试应用是否正常工作。比如我们想访问127.0.0.1:8000时,能够显示欢迎语句。

在views.py新增index函数:

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse

def index(request):

return HttpResponse(u"欢迎光临!")

index()返回 HttpResponse 对象,可以显示在网页上,现在需要规定那个网址能使用这个函数,也就是需要在urls.py进行修改:

from django.conf.urls import url

from django.contrib import admin

from hrskill import views as hrskill_views #新增

urlpatterns = [

url(r'^$', hrskill_views.index), #新增url解析规则,什么网址对应什么函数

url(r'^admin/', admin.site.urls),

]

其中网址写法符合正则表达式规则。

然后运行开发服务器 python manage.py runserver,打开浏览器,输入127.0.0.1:8000,结果如下:

image.png

1.5 使用模板(templates)进行交互

前面通过HttpResponse 来把内容显示到网页上,非常简单,能做的事也很少。

更多的我们是用模板templates的方法,就是事先写好html文件,然后直接返回这个html文件,这样就可以美化页面。

在hrskill文件夹下新建templates文件夹,然后新建一个index.html文件。

/templates/index.html内容如下:

欢迎使用

欢迎跟着朱老师学Django.

然后修改/hrskill/views.py如下:

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse #可以注释掉

def index(request):

return render(request, 'index.html') #修改为这样即可

#return HttpResponse(u"欢迎光临!")

然后可以刷新下网页(由于之前开发服务器一直运行,修改views.py会自动生效,无需重启,非常方便开发调式),结果已经更新。完美。

image.png

1.6 对模板进行渲染

上面功能还是很单一,只能返回写好的html文件。服务器更强大的应该是动态更新html文件,可以交互,比如不同用户访问,通过后台查询账号对应用户姓名,显示个性化欢迎语。

修改/templates/index.html内容如下:

欢迎使用

{ {name}},欢迎跟着朱老师学Django.

修改/hrskill/views.py如下:

from django.shortcuts import render

def index(request):

name = '朱锋' #模拟获取后台获取用户姓名,这里省略

return render(request, 'index.html',{'name':name}) #注意传name参数给前端

刷新网页,效果如下:

image.png

1.7 前端传参数给后台

很多时候,用户需要在前端网页输入某些关键字,然后传递给后台,后台根据这些参数进行处理,并返回结果。

这里简单模拟下用户在前端网页输入数字后,后台获取数字后加10返回,显示。

首先修改/templates/index.html内容如下:

欢迎使用

欢迎跟着朱老师学Django.

Go!

$(document).ready(function() {

$("#sum").click(function() {

var ne_str = $("#name").val();

$.ajaxSettings.async = false;

$.getJSON("/search/",{"name":ne_str}, function(ret) {

document.getElementById("p1").innerHTML = ret['data']

});

});

});

由于使用Jquery,需要导入,将相应js文件放入/hrskill/static/js目录下(自己新建)。

同时上面html文件中增加了一个表单form及对应的动作,包括一个输入框input,一个提交按钮,通过JavaScript的Ajax技术获取后台数据,获取数据后修改p1内容。

此时刷新网页,效果如下:

image.png

此时点击Go应该没有任何反应,因为后台没进行后台修改。

接下来我们要修改后台处理逻辑。

首先增加一个url网址对应的views函数。

修改/hringo/urls.py如下:

from django.conf.urls import url

from django.contrib import admin

from hrskill import views as hrskill_views #新增

urlpatterns = [

url(r'^$', hrskill_views.index), #新增url解析规则,什么网址对应什么函数

url(r'^search/$', hrskill_views.search), #新增search Url对应view中函数

url(r'^admin/', admin.site.urls),

]

此时点击Go,Django后台会报错,因为没有修改views.py。

修改/hrskill/views.py如下:

from django.shortcuts import render

# Create your views here.

from django.http import HttpResponse

import json #新增json处理

def index(request):

name = '朱锋' #模拟获取后台获取用户姓名,这里省略

return render(request, 'index.html',{'name':name}) #修改为这样即可

def search(request): #新增search函数

name = request.GET['name']

ret = {}

ret['data'] = '你输入的字符串是——{}'.format(name)

return HttpResponse(json.dumps(ret),content_type='application/json')

现在我们在输入框输入任何字符串,点击“Go”,提交后看看效果。(如果没响应,建议重启开发服务器再试试)。

输入“今天天气真好”,然后点击Go,效果如下:

点击前.png

点击后.png

偶尔可能犯迷糊,参数传递有问题,重新加载正常,需要前端大牛帮忙解决

以上,我们已经简单介绍了Django,包括网页的基本交互,接下来就是丰富处理逻辑,美化前端页面,都在上面的框架内完成。

2 前端优化——AdminLTE、Bootstrap、Echarts

为了使前端页面更美观,也使得交互更近优化,我们可以学习一些基本的前端技术的使用,如:

Bootstrap简洁、直观、强悍的前端开发框架,让web开发更迅速、简单。

AdminLTE,是基于Bootstrap3高度可定制的响应式管理模板,是网页更简单。

Echarts开源免费的可视化图表。

上述工具,自己查看教程学习,下载相应的js文件,放置合适路径。因为我也只是会用

3 最终实现

回到一开始的项目需求,按人员或技能查询并用合适图表对比显示分析。

首先看看后台Mysql两个数据库结构:

staff_skill表格式,提供人员技能掌握情况。

image.png

training_record表样例,提供人员培训记录。

image.png

3.1 HTML文件设计

总共设计3个html页面,分别是首页index.html、人员查询页面searchstaff.html和技能查询页面searchskill.html。

下载相应的js、css文件,放到/hrskill/static/下合适路径。

index.html如下(说实话,可能有些css、js文件是不必要,但是我不知道):

欢迎使用

人员技能管理系统

人员查询searchstaff.html文件如下:

人员查询

人员技能管理系统

姓名:

查询

$(document).ready(function() {

$("#sum").click(function() {

var name_str = $("#name").val();

//alert(name_str)

$.ajaxSettings.async = false;

$.getJSON("/getstaff/",{"username":name_str}, function(ret) {

document.getElementById("remark").innerHTML = ret['remark']

var cols = ret['cols']

var a_skills = ret['a_skills']

var cols_train = ret['cols_train']

var train_record = ret['train_record']

var $table = $('#table');

var $table_train = $('#table_train');

$table.bootstrapTable('destroy');

$table_train.bootstrapTable('destroy');

$(function() {

$table.bootstrapTable({

detailView: true,

data: a_skills,

dataType: "json",

search: true, //显示搜索框

columns: cols,

onExpandRow: function(index, row, $detail) {

InitSubTable(index, row, $detail);

}

});

InitSubTable = function(index, row, $detail) {

var b_skills = row.b_skills;

var cur_table = $detail.html('

').find('table');

$(cur_table).bootstrapTable({

data: b_skills,

columns: cols,

});

};

});

$(function(){

$table_train.bootstrapTable({

data: train_record,

dataType: "json",

search: true, //显示搜索框

columns: cols_train,

});

});

});

});

});

通过输入被查询人员姓名,查询显示其技能和培训情况。

技能查询searchsskill.html文件如下:

未完待续,大家可以完成

通过输入被查询技能名称,查询显示人员掌握情况。

3.2 后台处理逻辑设置

修改urls.py如下:

from django.conf.urls import url

from django.contrib import admin

from hrskill import views as hrskill_views #新增

urlpatterns = [

url(r'^$', hrskill_views.index), #新增url解析规则,什么网址对应什么函数

url(r'^searchstaff/$', hrskill_views.searchstaff), #新增searchstaff函数

url(r'^searchskill/$', hrskill_views.searchskill), #新增searchskill函数

url(r'^admin/', admin.site.urls),

]

修改views.py如下:

from django.shortcuts import render

from django.http import HttpResponse

import pandas as pd

import json #新增json处理

import pymysql #操作数据库

ip = '127.0.0.1'

user = 'root'

password = 'root'

db = 'hrinfo'

def index(request):

name = '朱锋' #模拟获取后台获取用户姓名,这里省略

return render(request, 'index.html',{'name':name}) #修改为这样即可

def staffinfo(request):

return render(request, 'searchstaff.html')

def skillinfo(request):

return render(request, 'searchskill.html')

#查询人员信息

def getstaff(request):

name = request.GET["username"]

conn = pymysql.connect(host=ip, port=3306, user=user, passwd=password, db=db,charset='utf8')

sql_skill = "SELECT * FROM staff_skill"

skills = pd.read_sql(sql_skill,conn)

skills = skills[skills['name']==name]

ret = {}

cols = []

col = ['name','skill_name','date','no','primary','middle','senior']

col_title = ['姓名','技能名称','认证日期','没听过','初级','中级','高级']

for i in range(len(col)):

col_f = {}

col_f['field'] = col[i]

col_f['title'] = col_title[i]

cols.append(col_f)

ret['cols'] = cols

a_skills = []

for a_skill,group in skills.groupby(['a_skill']):

row = {}

date = max(group['skill_date'])

num = len(group)

no = len(group[group['skill_level']=='没听过'])

primary = len(group[group['skill_level']=='初级'])

middle = len(group[group['skill_level']=='中级'])

senior = len(group[group['skill_level']=='高级'])

row['name'] = name

row['skill_name'] = a_skill

row['date'] = date

row['no'] = '{}/{}'.format(no,num)

row['primary'] = '{}/{}'.format(primary,num)

row['middle'] = '{}/{}'.format(middle,num)

row['senior'] = '{}/{}'.format(senior,num)

b_skills = []

for b_skill ,b_group in group.groupby(['b_skill']):

b_row = {}

b_row['name'] = name

b_row['skill_name'] = b_skill

b_row['date'] = date

num = len(b_group)

no = len(b_group[b_group['skill_level']=='没听过'])

primary = len(b_group[b_group['skill_level']=='初级'])

middle = len(b_group[b_group['skill_level']=='中级'])

senior = len(b_group[b_group['skill_level']=='高级'])

b_row['no'] = '{}/{}'.format(no,num)

b_row['primary'] = '{}/{}'.format(primary,num)

b_row['middle'] = '{}/{}'.format(middle,num)

b_row['senior'] = '{}/{}'.format(senior,num)

b_skills.append(b_row)

row['b_skills'] = b_skills

a_skills.append(row)

ret['a_skills'] = a_skills

sql_train = "SELECT * FROM training_record"

trains = pd.read_sql(sql_train,conn)

cj_trains = trains[trains['name']==name]

zj_trains = pd.DataFrame()

for i in trains.index:

speaker = trains.loc[i]['speaker']

if name in speaker:

zj_trains = zj_trains.append(trains.loc[i],ignore_index=True)

re_train = []

if not zj_trains.empty:

for topic in set(zj_trains['train_topic']):

topic_train = zj_trains[zj_trains['train_topic'] == topic][['train_date','days','train_class','train_loc']]

topic_train = topic_train.drop_duplicates()

row = dict(topic_train.iloc[0])

row['name'] = name

row['topic'] = topic

row['isspeaker'] = '是'

re_train.append(row)

if not cj_trains.empty:

for i in cj_trains.index:

topic = cj_trains.loc[i]['train_topic']

if zj_trains.empty or (topic not in set(zj_trains['train_topic'])):

row = dict(cj_trains.loc[i][['train_date','days','train_class','train_loc']])

row['name'] = name

row['topic'] = topic

row['isspeaker'] = '否'

re_train.append(row)

ret['train_record'] = re_train

cols_train = []

col_train = ['name','topic','train_date','days','train_class','train_loc','isspeaker']

col_title_train = ['姓名','培训名称','培训日期','培训天数','培训类型','培训地点','是否为讲师']

for i in range(len(col_train)):

col_f = {}

col_f['field'] = col_train[i]

col_f['title'] = col_title_train[i]

cols_train.append(col_f)

ret['cols_train'] = cols_train

#写评语

num = len(skills)

senior = len(skills[skills['skill_level']=='高级'])

middle = len((skills[skills['skill_level']=='中级']))

primary = len((skills[skills['skill_level']=='初级']))

no = len((skills[skills['skill_level']=='没听过']))

num_zj = len(zj_trains)

num_cj = len(zj_trains) + len(cj_trains)

remark = "
{}同学,在全部的{}个知识点中,掌握情况大概如下:高级{}/{},中级{}/{},初级{}/{},没听过{}/{}。\

近期主讲{}次培训,参加{}次培训。
".format(name,num,senior,num,middle,num,primary,num,no,num,num_zj,num_cj)

ret['remark'] = remark

return HttpResponse(json.dumps(ret),content_type='application/json')

由于时间关系,后台处理逻辑实现比较乱,建议单独一个模块,写各种函数,实现数据处理功能。

现在我们可以看看网页的效果

点击左侧“人员查询”:

image.png

输入姓名“XX”,点击查询:

image.png

由于时间关系,技能查询功能未实现,同时显示方式、评价都有很多优化的地方,使得交互更加友好。

期待你们的完善。

全部教程到此结束,砖已抛出,期待你们的玉。

Python真是零基础编程的神器!

你可能感兴趣的:(怎么用python搭建网站)