技术标签: python css django html bootstrap
使用的是django3.0版本,数据库使用的是mysql1.0版本的
项目所包含的文件如下图:
需要实现功能:
1、用户输入的用户名,密码和验证码能在后台获取
2、将获取的数据进入到数据库查找
3、成功登录后,将用户存储一个cookie在浏览器的session里面
4、判断本机用户是否有cookie存储在session里,有就可以访问系统里的所有页面,否则直接跳到登录页面。
采用form组件来实现数据的改查,MiddleForm中间件来控制访问其他页面的条件,未登录过则不可以访问系统其他页面。
# 登录Form
class LoginForm(BootstrapForm):
username = forms.CharField(label="用户名",
widget=forms.TextInput)
password = forms.CharField(label="密码",
widget=forms.PasswordInput(render_value=True))
image_code = forms.CharField(label='验证码', widget=forms.TextInput)
def clean_password(self):
"""将得到的密码加密"""
pwd = self.cleaned_data.get('password')
return md5(pwd)
# 中间件
class M1(MiddlewareMixin):
"""中间件设置每个网页的访问限制"""
def process_request(self, request):
# 判断地址栏地址决定网页是否可直接访问
if request.path_info in ['/login/', '/img_code/']:
return # return 后执行下一步方法
# 判断该用户是否在session里有存储信息,有则可以进入
if request.session.get('info'):
return
# 无存储信息,进入到登录页面
return redirect('/login')
# def process_response(self, request, response):
# print("走了")
# return response # 不能忘了这一步
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel="stylesheet" type="text/css" href="{%static 'css/bootstrap.min.css'%}">
<script src="{% static 'plugin/jquery-3.6.0.js' %}"></script>
<script src="{% static 'plugin/bootstrap.min.js' %}"></script>
<style type="text/css">
.login_form{
position: fixed;
width: 350px;
height: 370px;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin:auto;
border-radius: 10px;
box-shadow: 14px 15px 19px -3px;
}
h2{
text-align: center;
margin-bottom: 18px;
margin-top: 30px;
}
input{
margin: 10px 0;
}
.form-group{
height: 74px;
margin-bottom: 0;
}
.form-group label{
height: 30px;
font-size: 16px;
margin-top: 8px;
}
input[type="submit"]{
font-size: 16px;
}
#id_image_code{
width: 61%;
}
img{
margin-top: 10px;
margin-left: -40px;
}
</style>
</head>
<body>
<div class="container">
<div class="login_form">
<h2>用户登录</h2>
<form class="form-horizontal" method="POST" novalidate>
{% csrf_token %}
<div class="form-group">
<label class="control-label col-sm-3">用户名</label>
<div class="col-sm-8">
{
{forms.username}}
<span style="color: red;">{
{forms.username.errors.0}}</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">密码</label>
<div class="col-sm-8">
{
{forms.password}}
<span style="color: red;">{
{forms.password.errors.0}}</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3">验证码</label>
<div class="col-sm-5">
{
{forms.image_code}}
<span style="color: red;">{
{forms.image_code.errors.0}}</span>
</div>
<div class="col-sm-4" style="padding: 0"><img src="/img_code"></div>
</div>
<input type="submit" class="btn btn-primary col-sm-4 col-sm-offset-4" value="登录">
</form>
</div>
</div>
</body>
</html>
效果演示图:
其中包括了员工信息管理,部门信息管理,靓号信息管理,管理员信息管理和订单信息管理。
这些页面的样式基本一致,只是存在着部分功能的不同,因此,采用django中模板继承的方法,将公共部分都写在母版里,再通过模板语言书写不同的样式部分。
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>员工管理系统</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
{%block css %}{%endblock%}
<script src="{% static 'plugin/jquery-3.6.0.js' %}"></script>
<script src="{% static 'plugin/bootstrap.min.js' %}"></script>
{%block js%}{%endblock%}
<style type="text/css">
th,td{
text-align: center;
}
</style>
</head>
<body style="position: relative;">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/staffsInfo">联通员工管理系统</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">信息管理 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="/staffsInfo">员工信息管理</a></li>
<li ><a href="/departsInfo">部门管理</a></li>
<li><a href="/niceTels">靓号管理</a></li>
<li><a href="/admins">管理员信息</a></li>
<li><a href="/orders">订单信息</a></li>
</ul>
</li>
<li><a href="/tasks">ajax测试页面</a></li>
<li><a href="/data_show">数据统计页面</a></li>
<li><a href="/upload">文件上传</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{
{request.session.info.name}}
<span class="caret">
<ul class="dropdown-menu">
<li><a href="#">个人中心</a></li>
<li><a href="#">我的信息</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout">注销</a></li>
</ul>
</span></a>
</li>
</ul>
</div>
</div>
</nav>
<div>
{% block content %}{% endblock%}
</div>
<!-- 分页 -->
<div class="container">
<nav aria-label="...">
<ul class="pagination">
{
{pages}}
</ul>
</nav>
</div>
</body>
</html>
{% extends 'layout.html' %}
{% block content %}
<div class="main">
<div class="container">
<div style="margin-bottom: 10px;">
<a href="add/" class="btn btn-success">
添加管理员
<span class="glyphicon glyphicon-plus"></span>
</a>
</div>
<div class="panel panel-default ">
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list"></span>
管理员信息列表
</div>
<table class="table table-bordered">
<thead >
<tr>
<th>ID</th>
<th>用户名</th>
<th>密码</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for admin in admins %}
<tr>
<th scope="row">{
{admin.id}}</th>
<td>{
{admin.username}}</td>
<td>{
{admin.password}}</td>
<td>
<a href="update/{
{admin.id}}" class="btn btn-primary btn-sm">密码重置</a>
<a href="delete/{
{admin.id}}" class="btn btn-danger btn-sm">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
展示图:
以下代码使用模板语言中的循环,获取数据库中对应的数据信息,然后展示在页面中。
其中密码重置和删除的地址对应的是视图函数所绑定的url执行对应的功能
{% for admin in admins %}
<tr>
<th scope="row">{
{admin.id}}</th>
<td>{
{admin.username}}</td>
<td>{
{admin.password}}</td>
<td>
<a href="update/{
{admin.id}}" class="btn btn-primary btn-sm">密码重置</a>
<a href="delete/{
{admin.id}}" class="btn btn-danger btn-sm">删除</a>
</td>
</tr>
{% endfor %}
点击删除后直接从数据库中删除对应数据。
订单页面,点击新建,弹出输入模态框。
{%block js%}
<script type="text/javascript">
$(function(){
var $btn_new = $('#btn_new')
var $btn1 = $('#btn1')
$btn_new.click(function(){
// alert('ok')
$('#myModal').modal('show')
})
$btn1.click(function(){
$('.error').empty(); //点击一开始就清空错误信息,在重新获取错误
$.ajax({
url: "/tasks/ajax/",
type: "post",
dataType: 'JSON',
data: $('#form').serialize() //转换以字典的格式传给后台
})
.done(function(dat){
console.log(dat.statu)
if (dat.statu == true){
// console.log('ok')
alert('添加成功!');
// 获取的是个Queryset,得取其中的对象,才能清空表单内容
$('#form')[0].reset();
// 添加成功后隐藏模态框
$('#myModal').modal('hide');
location.reload();
}
else {
$.each(dat.errors,function(name, error){
$('#id_' + name).next().html(error)
$('#id_' + name).focus(function(){
$(this).next().empty()
})
})
}
})
.fail(function(){
console.log('失败了')
})
})
})
</script>
{%endblock%}
使用的是百度的echarts来进行绘图,还可以使用highcharts,echarts是借鉴于highcharts。数据暂时是在后台写定,实际是从数据库获取,但是基本写法一致。
{% load static %}
{%block js%}
<script type="text/javascript" src="{% static 'js/echarts.js' %}"></script>
<script type="text/javascript">
/**
*
报错:
Uncaught Error: Initialize failed: invalid dom.
init$1 http://127.0.0.1:8000/static/js/echarts.js:30192
<anonymous> http://127.0.0.1:8000/data_show/:21
原因:
我的js代码段写在body标签之前,浏览器加载时会先去解析js代码,当浏览器执行document.getElementById('main')时,由于id为main的dom对象还未被创建,报错Initialize failed: invalid dom.
解决:
加上jquery的ready方法
**/
$(function(){
Initbar();
Initline();
Initpie();
})
function AjaxDatas(dat, option, myChart){
$.ajax({
url: '/data_show/data_request/',
type: 'POST',
data: {
num: dat},
dataType:'JSON'
}).done(function(data){
console.log(data);
if (dat == 3){
option.series[0].data = data.series;
}
else{
option.legend.data = data.legend_data;
option.xAxis.data = data.xAxis_data;
option.series = data.series;
}
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
})
}
function Initbar(){
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('bar'));
// 指定图表的配置项和数据
var option = {
title: {
text: '员工业绩数据显示',
left: 'center'
},
tooltip: {
},
legend: {
data: [],
bottom: 0
},
xAxis: {
data: [],
bottom: 0
},
yAxis: {
},
series: []
};
AjaxDatas(1, option, myChart);
}
function Initline(){
var chartDom = document.getElementById('line');
var myChart = echarts.init(chartDom);
var option;
option = {
title: {
text: '公司一周业绩数据展示',
left: 'center'
},
tooltip: {
},
legend: {
data: [],
bottom: 0
},
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value'
},
series: []
};
AjaxDatas(2, option, myChart);
}
function Initpie(){
var chartDom = document.getElementById('pie');
var myChart = echarts.init(chartDom);
var option;
option = {
title: {
text: '员工业绩占比图',
subtext: '上海分公司',
left: 'center'
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left',
bottom:0
},
series: [
{
name: '业绩量',
type: 'pie',
radius: '50%',
data: [],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
AjaxDatas(3, option, myChart);
}
</script>
{%endblock%}
能够上传各种数据,例子为上传图片,读取后并将其存储在数据库,存取的图片信息是展示地址,通过浏览器地址栏输入地址就可以访问。
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">文件信息上传ModelForm方式(混合数据)</h3>
</div>
<div class="panel-body">
<form method="POST" enctype="multipart/form-data" novalidate>
<!-- 通过ModelForm组件,创建输入框,然后获取数据,判断对错,保存到数据库。 -->
<!-- {% csrf_token %}使用来赋予权限能够通过POST方法想后台发送数据
{% csrf_token %} -->
{% csrf_token %}
{% for form in forms2 %}
<div class="form-group" >
<label>{
{form.label}}</label>
{
{form}}
<span class="error" style="color: red">{
{form.errors.0}}</span>
</div>
{% endfor %}
<input type="submit" value="提交3" class="btn btn-info" name="submit">
</form>
</div>
</div>
</div>
<div class="main">
<div class="container">
<div class="panel panel-default ">
<div class="panel-heading">
<span class="glyphicon glyphicon-th-list"></span>
文件信息列表
</div>
<table class="table table-bordered">
<thead >
<tr>
<th>ID</th>
<th>用户名</th>
<th>头像</th>
<th>密码</th>
</tr>
</thead>
<tbody>
{% for file in files %}
<tr>
<th scope="row">{
{file.id}}</th>
<td>{
{file.username}}</td>
<td>
<img src="/{
{file.file}}" style="height: 100px;">
</td>
<td>{
{file.password}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
关键部分:
<!-- 通过ModelForm组件,创建输入框,然后获取数据,判断对错,保存到数据库。 -->
<!-- {% csrf_token %}使用来赋予权限能够通过POST方法想后台发送数据
{% csrf_token %} -->
{% csrf_token %}
{% for form in forms2 %}
<div class="form-group" >
<label>{
{form.label}}</label>
{
{form}}
<!-- 将错误显示在页面上 -->
<span class="error" style="color: red">{
{form.errors.0}}</span>
</div>
{% endfor %}
import os.path
from django.conf import settings
from InfosShow import models
from django.http import HttpResponse
from django.shortcuts import render, redirect
from InfosShow.static.utils.pagination import Pagination
from InfosShow.static.utils.form import FileForm, FileModelForm
def upload(request):
forms1 = FileForm()
forms2 = FileModelForm()
files = models.FileInfo.objects.all()
pagination = Pagination(request, files, plus=3)
content = {
'forms1': forms1,
'forms2': forms2,
'files': pagination.queryset_list,
'pages': pagination.run()
}
if request.method == 'GET':
return render(request, 'upload_test.html', content)
# 读取上传来的文件,获得一个对象
file_object = request.FILES.get('file')
submit = request.POST.get('submit')
img_show_path = ''
if file_object:
print(submit)
name = file_object.name
print(request.POST.get('submit'))
print(name)
# 地址拼接
# 网页查看图片的地址
# static使用与存放静态文件js, css, html等的,而么media是用于存放上传来的数据的。
# media/img1.jpg
img_show_path = os.path.join('media', name) # 相对路径
# 图片保存位置
# /home/jisoo/Django_project/SIMS/media/img1.jpg
# img_show_path = os.path.join(settings.MEDIA_ROOT, name) # 绝对路径
# img_path = os.path.join('InfosShow', 'static', 'img', name) # 保存在static下的路径
f = open(img_show_path, mode='wb')
# 上传的文件是一块一块的,因此需要一块块读取然后进行存储。用到chunks方法
for chunk in file_object.chunks():
f.write(chunk)
f.close()
if submit == '提交2':
forms1 = FileForm(data=request.POST, files=request.FILES)
if forms1.is_valid():
print(forms1.cleaned_data)
else:
print(forms1.errors)
return render(request, 'upload_test.html', {
'forms1': forms1, 'forms2': forms2})
elif submit == '提交3':
forms2 = FileModelForm(data=request.POST, files=request.FILES)
if forms2.is_valid():
forms2.instance.file = img_show_path
forms2.save()
else:
return render(request, 'upload_test.html', {
'forms1': forms1, 'forms2': forms2})
return redirect('/upload')
要是media得需要提前配置
在urls.py中进行配置:
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
]
在settings.py中进行配置:
import os
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
具体的一些细节功能没有拉出来单讲,比如
看到这的大神或是跟我一样的初学者,如果我这有任何问题,或是你有相关这些的问题,欢迎私信评论,我会认真学习,并讨论。
文章浏览阅读4.4k次,点赞2次,收藏16次。写这篇文章的由来是因为后边要用这个工具,但是由于某些原因有部分小伙伴和童鞋们可能不会安装此工具,为了方便小伙伴们和童鞋们的后续学习和不打击他们的积极性,因为80%的人都是死在工具的安装这第一道门槛上,这门槛说高也不高说低也不是太低。所以就抽时间水了这一篇文章。_eclipse安装教程
文章浏览阅读4.1w次,点赞12次,收藏193次。小编为大家收集了11个web前端开发,大企业实战项目案例+5W行源码!拿走玩去吧!1)小米官网项目描述:首先选择小米官网为第一个实战案例,是因为刚开始入门,有个参考点,另外站点比较偏向目前的卡片式设计,实现常见效果。目的为学者练习编写小米官网,熟悉div+css布局。学习资料的话可以加下web前端开发学习裙:600加上610再加上151自己去群里下载下。项目技术:HTML+CSS+Div布局2)迅雷官网项目描述:此站点特效较多,所以通过练习编写次站点,学生可以更多练习CSS3的新特性过渡与动画的实_前端项目实战案例
文章浏览阅读73次。素数,不同的质数,各种各样的问题总是遇到的素数。以下我们来说一下求素数的一种比較有效的算法。就是筛法。由于这个要求得1-n区间的素数仅仅须要O(nloglogn)的时间复杂度。以下来说一下它的思路。思路:如今又1-n的数字。素数嘛就是除了1和本身之外没有其它的约数。所以有约数的都不是素数。我们从2開始往后遍历,是2的倍数的都不是素数。所以我们把他们划掉然后如...
文章浏览阅读532次,点赞9次,收藏14次。探索Keras DCGAN:深度学习中的创新图像生成项目地址:https://gitcode.com/jacobgil/keras-dcgan在数据驱动的时代,图像生成模型已经成为人工智能的一个重要领域。其中,Keras DCGAN 是一个基于 Keras 的实现,用于构建和训练 Deep Convolutional Generative Adversarial Networks(深度卷积生...
文章浏览阅读116次。今天在搭建springcloud项目时,发现如上错误,顺便整理一下这个异常:1. mapper.xml的命名空间(namespace)是否跟mapper的接口路径一致<mapper namespace="com.baicun.springcloudprovider.mapper.SysUserMapper">2.mapper.xml接口名是否和mapper.java接..._spring-could org.apache.ibatis.binding.bindingexception: invalid bound state
文章浏览阅读1.1k次。四种高效数据库设计思想——提高查询效率:设计数据库表结构时,我们首先要按照数据库的三大范式进行建立数据。1. 1NF每列不可拆分2. 2NF确保每个表只做一件事情3. 3NF满足2NF,消除表中的依赖传递。三大范式的出现是在上世纪70年代,由于内存资源比较昂贵,所以严格按照三大范式进行数据库设计。而如今内存变得越来越廉价,在考虑效率和内存的基础上我们可以做出最优选择以达到最高效率。_数据库为什么能提高效率
文章浏览阅读302次。一. HTML标签分类1.根据标签个数分类。 单标签:只有一个标签。 <br>, <hr>,<img>,<meta>, 实现一个特定的功能。 双标签:既有开始标签,也有结束标签。 Html,head,Body,title,h1~h6,p,a,ul,li,ol,strong,em。2.根据标签特性分类(网页效果)。 2.1行属性..._ol是单标记还是双标记
文章浏览阅读1.6k次。应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数 据库连接参数、启动参数等。配置主要有以下几个特点:配置是独立于程序的只读变量配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置配置伴随应用的整个生命周期配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。配置可以有多种加载方式常见的有程序内部_基于配置是什么意思
文章浏览阅读170次。Glib库实现了一个非常重要的基础类--GObject,这个类中封装了许多我们在定义和实现类时经常用到的机制: 引用计数式的内存管理 对象的构造与析构 通用的属性(Property)机制 Signal的简单使用方式 很多使用GObject..._
文章浏览阅读6.3k次,点赞2次,收藏9次。在 golang 中若写定时脚本,有两种实现。一、基于原生语法组装func DocSyncTaskCronJob() { ticker := time.NewTicker(time.Minute * 5) // 每分钟执行一次 for range ticker.C { ProcTask() }}func ProcTask() { log.Println("hello world")}二、基于 github 中封装的 cron 库实现package taskimport (_golang 定时任务
文章浏览阅读2.1k次。 来源:http://blog.csdn.net/clever101/archive/2008/10/18/3096049.aspx 声明:本文章是我整合网上的资料而成的,其中的大部分文字不是我所为的,我所起的作用只是归纳整理并添加我的一些看法。非常感谢引用到的文字的作者的辛勤劳动,所参考的文献在文章最后我已一一列出。 对关注性能的程序开发人员而言,一个好的计时部件既是益友,也_vc 通过线程和 sleep 获取精准时间
文章浏览阅读58次。公司突然说要进行wap开发了,以前从没了解过,但我却异常的兴奋,因为可以学习新东西了,呵呵,我们大家一起努力吧。首先说说环境的搭建。可以把.wml的文件看做是另一种的html进行信息的展示,但并不是所有的浏览器都支持,好用的有Opera,还有WinWap。编写wml文件语法比较严格,不好的是我还没有找到好的提示工具,就先用纯文本吧。我找到了一个很好的学习网站:http://w3sc..._winwap学习