Django员工管理系统(ems)
- 需求分析:
1.实现管理员的注册、登陆页面注册:用户名、真实名字、密码、确认密码、性别、验证码用户名需要判断是否合法、是否存在,loading图片提示密码和确认密码是否相同,loading图片提示验证码是否正确,loading图片提示点击提交时:判断信息是否正确,如错误弹窗提示,如正确,重定向到登陆页面登陆:用户名、密码、选框(记住我7天)点击提交时:判断该用户名密码是否正确,如错误弹窗提示,如正确,重定向到主页面
2.实现查看、增加、删除、修改员工信息页面查看:分页显示员工数据,下方有 上一页,页码,下一页,如没有则相应不显示点击则跳转到相应页面每条员工数据后有删除、修改 a标签,下方有增加员工信息按钮点删除,提示是否删除框,点修改,则跳转到修改页面,点增加,跳转到增加页面增加:头像、员工名、年龄、薪水,提交按钮点提交,信息添加到最后一个,并跳转到查看页面的最后一页删除:判断是否删除,如是,则删除,跳转到原查看页面注:如删除的员工为最后一个,则跳转到最后一页修改:自动获取要修改员工的信息,提交按钮提交后跳转到原查看页面注:以上页面都需要判断是否登陆成功,如果未登录,则强制登陆(跳转到登陆页面)
- 前期准备
建立虚拟环境:python3.5、django2.0.6、mysql5.5.6、pip(下载第三方库的工具)、virtualenv(虚拟环境)、virtualenvwrapper(虚拟环境管理工具)、mysqlclient(Django连接数据库的第三方库)、pillow(验证码第三方包)
IDE:pycharm
navicat: 查看数据库(也可没有)
- 创建Django项目(项目名 ems2_project)
1.创建两个APP:user、emp
python manage.py startapp userpython manage.py startapp emp# user:管理员注册登陆# emp:员工的增删查改
2.项目setting里相关配置
挂载app设置数据库为mysql,并添加相应配置设置session存活日期:# SESSION_EXPIRE_AT_BROWSER_CLOSE = True增加管理者头像图片所需的文件位置: /static (在项目根目录下创建:所有的静态资料都放在下面)把存放图片的文件添加到静态资源查找位置# STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
3.项目urls里相关配置
导入app里的urls (每个app下创建自己的urls.py文件)urlpatterns = [path('admin/', admin.site.urls),path('user/', include("user.urls")),path('emp/', include("emp.urls")),]注:每个app里功能对应的url应放在app里
4.user相关功能实现
model操作:创建User类并创建相应的属性、类型class User(models.Model):username = models.CharField(max_length=20)name = models.CharField(max_length=20)passwd = models.CharField(max_length=20)sex = models.CharField(max_length=10)创建完毕后,执行迁移命令,生成对应数据表python manage.py makemigratonspython manage.py migrate
urls操作:先创建urls.py文件加入 app_name='user' :创建app命名空间,建立软连接再创建相应url地址:urlpatterns = [path('login/', views.login, name = 'login'),path('loginlogic/', views.loginlogic, name = 'loginlogic'),path('regist/', views.regist, name = 'regist'),path('registlogic/', views.registlogic, name = 'registlogic'),path('checkname/', views.checkname, name = 'checkname'),path('checknumber/', views.checknumber, name = 'checknumber'),path('getcaptcha/', views.getcaptcha, name = 'getcaptcha'),]注:name为各url命名空间
view操作:(创建视图函数)注:创建相应的htnl页面注册:def regist(request):return render(request, "user/regist.html")注册相应判断:def registlogic(request):# 获取相应参数属性username = request.POST.get("username")name = request.POST.get("name")pwd = request.POST.get("pwd")repwd = request.POST.get("repwd")sex = request.POST.get("sex")number = request.POST.get("number")code = request.session.get("code")# 用户名、密码、验证码判断if code.lower() == number.lower():res = User.objects.filter(username=username)if not res and name and pwd == repwd:User.objects.create(username=username, name=name, passwd=pwd, sex=sex)return HttpResponse("1")return HttpResponse("0")注册中输入用户名之后判断:def checkname(request): ...注册中输入验证码之后判断:def checknumber(request): ...注册中的验证码显示:def getcaptcha(request):image = ImageCaptcha()code = random.sample(string.ascii_lowercase+string.ascii_uppercase+string.digits,5)random_code = ''.join(code)request.session['code'] = random_codedata = image.generate(random_code)return HttpResponse(data, "image/png")注:需要验证码相关文件 captcha登陆:def login(request):# 先判断是否有cookie值 中文需要解码username = request.COOKIES.get("username")if username:username = username.encode('latin-1').decode('utf-8')pwd = request.COOKIES.get("pwd")message = User.objects.filter(username=username, passwd=pwd)# 如cookie值正确,直接进入主页面if message:request.session['life'] = Truereturn redirect("emp:empList")# 没有或错误的cookie,进入登陆页面return render(request, "user/login.html")登陆相应判断:def loginlogic(request):# 获取用户名,密码 用户名需编码username = request.POST.get("username")pwd = request.POST.get("pwd")# 判断信息是否正确message = User.objects.filter(username=username, passwd=pwd)if username:username = username.encode('utf-8').decode('latin-1')# 如正确,则判断是否记住密码,是否设置cookieif message:res = HttpResponse("1")if request.POST.get("remeber"):res.set_cookie("username", username, max_age=7 * 24 * 3600)res.set_cookie("pwd", pwd, max_age=7 * 24 * 3600)return resreturn HttpResponse("0")
5.emp相关功能实现
model操作:class Emp(models.Model):headpic = models.ImageField(upload_to="pics")name = models.CharField(max_length=20)salary = models.CharField(max_length=20)age = models.IntegerField()注:图片需指定存储位置,本文为 pics文件下(不需要自己创建,django会自动创建)
urls操作:app_name = "emp"urlpatterns = [path("empList/", views.empList, name = "empList"),path("addEmp/", views.addEmp, name = "addEmp"),path("addEmpLogic/", views.addEmpLogic, name = "addEmpLogic"),path("updateEmp/", views.updateEmp, name = "updateEmp"),path("updateEmplogic/", views.updateEmplogic, name = "updateEmplogic"),path("deleteEmp/", views.deleteEmp, name="deleteEmp"),]
view操作:(创建视图函数)主页面(查看):def empList(request):# 默认查看第一页,每页三条数据number = request.GET.get("number", 1)pagtor = Paginator(Emp.objects.all(), per_page=3)# 判断是否为增加操作,如是,需要跳转到最后一页if request.session.get("add"):number = pagtor.num_pagesrequest.session['add'] = Falsepage = pagtor.page(number)# 把页面对象传递给html页面return render(request, 'emp/emplist.html', {'emps': page})增加:def addEmp(request):return render(request, 'emp/addEmp.html')增加判断操作:def addEmpLogic(request):# 获取属性参数head_pic = request.FILES.get("head_pic")name = request.POST.get("name")salary = request.POST.get("salary")age = request.POST.get("age")# 设置图片名head_pic.name = generteUUID(head_pic.name)# 加入数据库事务try:with transaction.atomic():Emp.objects.create(headpic=head_pic, name=name, salary=salary, age=age)# 设置增加操作request.session["add"] = Truereturn redirect('emp:empList')except:return HttpResponse("添加失败")# 给图片头像设置随机文件名def generteUUID(head_pic):id = str(uuid.uuid4())extend = os.path.splitext(head_pic)[1]return id + extend修改:def updateEmp(request):# 接收对应员工的id,和对应页数id = request.GET.get("id")page = request.GET.get("number")request.session['number'] = pageemp = Emp.objects.get(id=id)return render(request, "emp/updateEmp.html", {"emp": emp})修改判断操作:def updateEmplogic(request):# 获取属性id = request.POST.get("id")head_pic = request.FILES.get("head_pic")name = request.POST.get("name")salary = request.POST.get("salary")age = request.POST.get("age")head_pic.name = generteUUID(head_pic.name)# 修改数据库中的值,保存emp = Emp.objects.get(id=id)emp.headpic = head_picemp.name = nameemp.age = ageemp.salary = salaryemp.save()# 传递页数给主页面number = request.session.get('number')url = reverse("emp:empList") + "?number=" + numberreturn redirect(url)删除:def deleteEmp(request):# 删除对应员工,传递页数id = request.GET.get("id")number = request.GET.get("number")Emp.objects.get(id=id).delete()url = reverse("emp:empList") + "?number=" + numberreturn redirect(url)
6.template(模板文件):
1.在template下先创建相应app名文件2.在app名文件下创建html页面3.采取模板继承
base.html:每个页面头部与尾部都是一样的,所以在父模板中渲染,如:右上角的时间<script>setInterval(function () {var time = new Date()var date = time.getFullYear() + "年" + (time.getMonth() + 1) + "月" + time.getDate() + "日" + time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds()document.getElementById("time").innerHTML = date}, 1000)</script>设置多个块,供子模版渲染
index.html:中javascript<script>{# 使用jQuery的ajax实现提交弹框 #}function login_sub() {var username = $("#username").val()var pwd = $("#pwd").val()var remeber = $("#remeber").prop("cheched")$.ajax({type: "POST",url: "{% url 'user:loginlogic' %}",data: "username=" + username + "&pwd=" + pwd + "&remeber=" + remeber +"&csrfmiddlewaretoken=" + "{{ csrf_token }}",success:function (msg) {if (msg === '1'){location.href = "{% url 'emp:empList' %}"}else {alert("用户名或密码错误!!!")}}})}</script>
regist.html:的jquery<script>{#换一张验证码#}function change() {var url = "{% url 'user:getcaptcha' %}?" + new Date().getTime()$("#num").attr('src',url)}{#提交弹框#}function regist_sub() {var username = $("#username").val()var name = $("#name").val()var pwd = $("#pwd").val()var repwd = $("#repwd").val()var sex = $("input[name='sex']:checked").val()var number = $("#number").val()$.ajax({type:"POST",url:"{% url 'user:registlogic' %}",data:"username=" + username + "&name=" + name +"&pwd=" + pwd + "&repwd=" + repwd + "&sex=" + sex +"&number=" + number +"&csrfmiddlewaretoken=" + "{{ csrf_token }}",success:function (msg) {if (msg === '1'){location.href = "{% url 'emp:empList' %}"}else {alert("注册信息有误!!!")}}})}{#三张图片:加载、正确、错误#}var img1 = "{% static 'img/5-121204193934-50.gif' %}"var img_right = "{% static 'img/right_3.jpg' %}"var img_worry = "{% static 'img/5-140FG95153-51.gif' %}"{#显示用户名输入后 相应的loading图片#}function checkname(t) {t.nextElementSibling.src = img1$.ajax({type: "POST",url: "{% url 'user:checkname' %}",data: "username=" + t.value + "&csrfmiddlewaretoken=" + "{{ csrf_token }}",success:function (msg) {if (msg === '1'){t.nextElementSibling.src = img_right}else {t.nextElementSibling.src = img_worry}}})}{#显示验证码输入后 相应的loading图片#}function checknumber(t) {t.nextElementSibling.src = img1$.ajax({type: "POST",url: "{% url 'user:checknumber' %}",data: "number=" + t.value + "&csrfmiddlewaretoken=" + "{{ csrf_token }}",success:function (msg) {if (msg === '1'){t.nextElementSibling.src = img_right}else {t.nextElementSibling.src = img_worry}}})}{#显示密码输入后 相应的loading图片#}function checkpwd(t) {t.nextElementSibling.src = img1setTimeout(function () {var content = t.valueif (content.length < 5){t.nextElementSibling.src = img_worry} else {t.nextElementSibling.src = img_right}},1000)}{#显示确认密码输入后 相应的loading图片#}function checkrepwd(t) {t.nextElementSibling.src = img1setTimeout(function () {if (t.value === $("#repwd").val() && t.value !== ''){t.nextElementSibling.src = img_right} else {t.nextElementSibling.src = img_worry}},1000)}</script>
empList.html:jquery:<script>{#删除:判断是否是最后一条数据,进行页数减一#}function del_emp(id) {if(confirm("是否删除???")){if ("{{ emps.start_index }}" === "{{ emps.end_index }}"){var number = "{{ emps.number|add:'-1' }}"}else {var number = "{{ emps.number }}"}location.href = "{% url 'emp:deleteEmp' %}?number=" + number + "&id=" + id}}</script>html:{#循环显示本页数据#}{% for emp in emps.object_list %}{# 每列交替换格式 #}{% if forloop.counter|divisibleby:'2' %}<tr class="row1">{% else %}<tr class="row2">{% endif %}{# 信息 #}<td>{{ emp.id }}</td><td><img src="{% static emp.headpic.url %}" width="50px" height="50px"></td><td>{{ emp.name }}</td><td>{{ emp.salary }}</td><td>{{ emp.age }}</td>{# 删除、修改 #}<td><a href="javascript:void(0)" onclick="del_emp({{ emp.id }})">delete_emp</a><a href="{% url 'emp:updateEmp' %}?id={{ emp.id }}&number={{ emps.number }}">update_emp</a></td></tr>{% endfor %}{# 上一页 #}{% if emps.has_previous %}<a href="{% url 'emp:empList' %}?number={{ emps.previous_page_number }}">上一页</a>{% endif %}{# 页码 #}{% for num in emps.paginator.page_range %}<a href="{% url 'emp:empList' %}?number={{ num }}"></a>{% if emps.number == num %}<span class="a">{{ num }}</span>{% else %}<span class="b">{{ num }}</span>{% endif %}{% endfor %}{# 下一页 #}{% if emps.has_next %}<a href="{% url 'emp:empList' %}?number={{ emps.next_page_number }}">下一页</a>{% endif %}
以上为创建员工管理系统全部步骤及部分重要代码。前后端全部代码