@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/../../../../../../:\djangoProject\djangoProject\djangoProject\the_online_test_system\.idea/dataSources/
|
||||
/dataSources.local.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/the_online_test_system.iml" filepath="$PROJECT_DIR$/.idea/the_online_test_system.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="django" name="Django">
|
||||
<configuration>
|
||||
<option name="rootFolder" value="$MODULE_DIR$" />
|
||||
<option name="settingsModule" value="the_online_test_system/settings.py" />
|
||||
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
|
||||
<option name="environment" value="<map/>" />
|
||||
<option name="doNotUseTestRunner" value="false" />
|
||||
<option name="trackFilePattern" value="migrations" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="TemplatesService">
|
||||
<option name="TEMPLATE_CONFIGURATION" value="Django" />
|
||||
<option name="TEMPLATE_FOLDERS">
|
||||
<list>
|
||||
<option value="$MODULE_DIR$/../the_online_test_system\templates" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LoginConfig(AppConfig):
|
||||
name = 'login'
|
@ -0,0 +1,59 @@
|
||||
import os
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageFilter
|
||||
import random
|
||||
import string
|
||||
|
||||
|
||||
def random_str(length=4):
|
||||
""" 随机字符串 默认长度 4
|
||||
|
||||
:param length: 默认长度 4
|
||||
:return:
|
||||
"""
|
||||
return ''.join(random.sample(string.ascii_letters, length))
|
||||
|
||||
|
||||
def random_color(s=1, e=255):
|
||||
""" 随机 RGB 颜色
|
||||
|
||||
:param s: 起始值, 0-255
|
||||
:param e: 结束时, 0-255
|
||||
:return: (r, g, b)
|
||||
"""
|
||||
return random.randint(s, e), random.randint(s, e), random.randint(s, e)
|
||||
|
||||
|
||||
def veri_code(length=4, width=160, height=40, size=28):
|
||||
""" 生成验证码图片
|
||||
|
||||
:param length: 验证码字符串长度
|
||||
:param width: 图片宽度
|
||||
:param height: 图片高度
|
||||
:param size: 字体大小
|
||||
:return: (验证码图片, 验证码字符串)
|
||||
"""
|
||||
# 创建Image对象
|
||||
image = Image.new('RGB', (width, height), (255, 255, 255))
|
||||
# 创建Font对象
|
||||
file = os.path.dirname(os.path.abspath(__file__))
|
||||
font = ImageFont.truetype(f'{file}/FZSTK.ttf', size)
|
||||
# 创建Draw对象
|
||||
draw = ImageDraw.Draw(image)
|
||||
# 随机颜色填充每个像素
|
||||
for x in range(0, width, 2):
|
||||
for y in range(height):
|
||||
draw.point((x, y), fill=random_color(64, 255))
|
||||
# 验证码
|
||||
code = random_str(length)
|
||||
# 随机颜色验证码写到图片上
|
||||
for t in range(length):
|
||||
draw.text((40 * t + 5, 5), code[t], font=font, fill=random_color(32, 127))
|
||||
# 模糊滤镜
|
||||
# image = image.filter(ImageFilter.BLUR)
|
||||
return image, code
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
img, code = veri_code()
|
||||
with open('test.png', 'wb') as f:
|
||||
img.save(f)
|
@ -0,0 +1,26 @@
|
||||
# Generated by Django 3.1.4 on 2022-04-08 08:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='UserInfo',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('identity', models.CharField(max_length=4, verbose_name='身份')),
|
||||
('name', models.CharField(max_length=32, verbose_name='姓名')),
|
||||
('id_number', models.CharField(max_length=32, verbose_name='学号/教师编号')),
|
||||
('phone', models.CharField(max_length=32, unique=True, verbose_name='手机')),
|
||||
('username', models.CharField(max_length=32, unique=True, verbose_name='账号')),
|
||||
('password', models.CharField(max_length=32, verbose_name='密码')),
|
||||
],
|
||||
),
|
||||
]
|
@ -0,0 +1,22 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class UserInfo(models.Model):
|
||||
"""
|
||||
用户列表
|
||||
用于记录用户基本信息
|
||||
"""
|
||||
identity = models.CharField(max_length=4, verbose_name="身份", blank=False, null=False)
|
||||
name = models.CharField(max_length=32, verbose_name="姓名", blank=False, null=False)
|
||||
id_number = models.CharField(max_length=32, verbose_name="学号/教师编号", blank=False, null=False)
|
||||
phone = models.CharField(max_length=32, verbose_name="手机", unique=True, blank=False, null=False)
|
||||
username = models.CharField(max_length=32, verbose_name="账号", unique=True, blank=False, null=False)
|
||||
password = models.CharField(max_length=32, verbose_name="密码", blank=False, null=False)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,252 @@
|
||||
body .bgimg img{
|
||||
position:absolute;
|
||||
width: auto;
|
||||
height: auto;
|
||||
width: 100%;
|
||||
top: 5px;
|
||||
height: 100%;
|
||||
left:0%;
|
||||
top: 0%;
|
||||
padding: 0;
|
||||
margin:0;
|
||||
z-index: 0;
|
||||
}
|
||||
body {
|
||||
font-family: PingFang SC,HarmonyOS_Regular,Helvetica Neue,Microsoft YaHei,sans-serif!important;
|
||||
font-weight: 400;
|
||||
overflow-x: auto;
|
||||
background-color: var(--graph_bg_regular);
|
||||
}
|
||||
|
||||
body {
|
||||
/* font-size: 14px; */
|
||||
font-size: 18px;
|
||||
line-height: 1.6;
|
||||
/* -webkit-text-size-adjust: 100%; */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
color: #18191c;
|
||||
background-color: #f6f7f8;
|
||||
/* min-width: 1100px; */
|
||||
}
|
||||
|
||||
.header-bgimg {
|
||||
position: absolute;
|
||||
width: auto;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left:0;
|
||||
z-index: 100;
|
||||
/* width: 1519.2px; */
|
||||
width: 1535px;
|
||||
/* height: 155px; */
|
||||
height: 120px;
|
||||
}
|
||||
header .header_bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0px;
|
||||
z-index: 1002;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
/* padding: 0 24px; */
|
||||
max-width: 2560px;
|
||||
/* width: 100%; */
|
||||
width: 1535px;
|
||||
height: 64px;
|
||||
}
|
||||
body ul {
|
||||
/* 取消小原点 */
|
||||
list-style-type: none;
|
||||
}
|
||||
body ul li {
|
||||
margin: 15px;
|
||||
}
|
||||
header .header_bar .left_entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
body a {
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
header span {
|
||||
color: white;
|
||||
/* font:14px "PingFang SC",HarmonyOs_re */
|
||||
}
|
||||
|
||||
.header_center {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
background-color: #fff;
|
||||
width: 400px;
|
||||
height: 32px;
|
||||
border-radius: 13px;
|
||||
}
|
||||
.header_bar .header_center .reseach {
|
||||
position: relative;
|
||||
/* display: inline; */
|
||||
top: -7px;
|
||||
/* left: 2px; */
|
||||
|
||||
width: 360px;
|
||||
height: 25px;
|
||||
line-height: 30px;
|
||||
border-radius: 13px;
|
||||
border-width: 0px;
|
||||
outline:none;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* header .header_bar .right_entry {
|
||||
position: relative;
|
||||
left: 100px;
|
||||
} */
|
||||
header right_last {
|
||||
position:absolute;
|
||||
}
|
||||
|
||||
header .header_bar .right_entry {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.right_last button {
|
||||
/* box-shadow: 5px 5px rgb(109, 247, 71); */
|
||||
/* blur:5px; */
|
||||
background:transparent;/*按钮背景透明 */
|
||||
/* background-color: pink; */
|
||||
border-radius: 14px;
|
||||
border-color: greenyellow;
|
||||
border: width 1px; /*边框透明*/
|
||||
outline:none; /*点击后没边框*/
|
||||
font-size: 24px;
|
||||
border-radius: 22px;
|
||||
}
|
||||
.mybody {
|
||||
position: relative;
|
||||
width: auto;
|
||||
width: 100%;
|
||||
left: -8px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
top: 60px;
|
||||
/* background: #000; */
|
||||
|
||||
}
|
||||
.body_left{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
|
||||
}
|
||||
.body_center {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: -220px;
|
||||
/* left: 900px; */
|
||||
width: 200px;
|
||||
/* height: 600px; */
|
||||
/* background-color: pink; */
|
||||
}
|
||||
|
||||
.body_center ul {
|
||||
/* position: absolute; */
|
||||
/* top: -200px;
|
||||
left: 50px; */
|
||||
position: relative;
|
||||
left: 20px;
|
||||
display:inline-block;
|
||||
|
||||
}
|
||||
.body_center ul li{
|
||||
margin: 10px;
|
||||
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
|
||||
font-weight: 700;
|
||||
/* font-style: italic; */
|
||||
font-size: 50px;
|
||||
position: center;
|
||||
}
|
||||
|
||||
|
||||
.body_right {
|
||||
position: absolute;
|
||||
display: block;
|
||||
/* width: 100px;
|
||||
height: 100px; */
|
||||
top: 70px;
|
||||
right: 0;
|
||||
/* background-color: #fff; */
|
||||
/* background: rgba(249, 246, 246, 0.3); */
|
||||
font-size: 20px;
|
||||
/* margin: 20px */
|
||||
}
|
||||
|
||||
.body_right table tr{
|
||||
margin: 20px;
|
||||
}
|
||||
.body_right input {
|
||||
width: 250px;
|
||||
height: 23px;
|
||||
border-color: aqua;
|
||||
border-radius: 18px;
|
||||
margin: 20px;
|
||||
}
|
||||
.body_right table .sign_ {
|
||||
position:relative;
|
||||
width: 220px;
|
||||
height: 40px;
|
||||
left: 50px;
|
||||
/*color: white;*/
|
||||
/*background:rgba(0,0,0, 0.3);*/
|
||||
font-size: 24px;
|
||||
}
|
||||
.body_right table span {
|
||||
/* border: red; */
|
||||
position: relative;
|
||||
/*background-color:aqua;*/
|
||||
/*left: 150px;*/
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 18px;
|
||||
margin: 30px;
|
||||
}
|
||||
/*.body_right table {*/
|
||||
/* margin: 0px;*/
|
||||
/* width: 50px;*/
|
||||
/*}*/
|
||||
.body_right table .add input{
|
||||
position: relative;
|
||||
margin: 10px;
|
||||
width: 15px;
|
||||
top: 4px;
|
||||
/*left: 20px;*/
|
||||
font-size: 16px;
|
||||
/*color: aliceblue;*/
|
||||
}
|
||||
.body_right table .add span {
|
||||
border-radius: 16px;
|
||||
border: 4px;
|
||||
border-color: aqua;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color:#aedab5;
|
||||
}
|
||||
|
||||
.body_right table .add a {
|
||||
width: 110px;
|
||||
border-radius: 16px;
|
||||
|
||||
background-color:#aedab5;
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,102 @@
|
||||
|
||||
.mybody{padding: 0;margin: 0;}
|
||||
|
||||
.body_left{
|
||||
position: relative;
|
||||
/* top: 40px; */
|
||||
/* width: 100vw;
|
||||
height: 100vh; */
|
||||
width: 750px;
|
||||
height: 600px;
|
||||
/* background: #82ccdd; */
|
||||
display:inline-block;
|
||||
/* justify-content: center;
|
||||
align-items: center; */
|
||||
}
|
||||
/* 显示框 */
|
||||
div.scroll-photo{
|
||||
position: absolute;
|
||||
/* width: 400px;
|
||||
height: 300px; */
|
||||
/* width: 800px; */
|
||||
width: 765px;
|
||||
height: 450px;
|
||||
left: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* 内置图片的排列总宽度 */
|
||||
div.photos{
|
||||
position: absolute;
|
||||
/* width: 1200px;
|
||||
height: 300px; */
|
||||
width: 22500px;
|
||||
height: 450px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
div.photos img{
|
||||
position: relative;
|
||||
/* width: 400px;
|
||||
height: 300px; */
|
||||
width: 800px;
|
||||
height: 450px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.index ul{
|
||||
position: absolute;
|
||||
display: grid;
|
||||
bottom: -10px;
|
||||
left: 40%;
|
||||
transform: translateX(-50%);
|
||||
list-style: none;
|
||||
width: 150px;
|
||||
grid-template: 1fr/repeat(3,1fr);
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
div.index ul::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 55px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
z-index: -1;
|
||||
/* background: #d63031; */
|
||||
background: rgb(0, 255, 255);
|
||||
}
|
||||
|
||||
div.index ul li{
|
||||
position: relative;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
color: #FFF;
|
||||
background: rgba(0,0,0,.5);
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
div.photos{
|
||||
animation:scroll 12s steps(3,end);
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
div.index ul::after{
|
||||
animation:index-scroll 12s steps(3,end);
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
/* 图片移动像素 */
|
||||
@keyframes scroll{
|
||||
to{
|
||||
transform: translateX(-2400px);
|
||||
}
|
||||
}
|
||||
/*下标移动像素 */
|
||||
@keyframes index-scroll{
|
||||
to{
|
||||
transform: translateX(165px);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
body {
|
||||
background-image: url(img/zc3.png);
|
||||
/* background-repeat: repeat-x; */
|
||||
position:relative;
|
||||
background-position-y: -100px;
|
||||
/* background-position-x: 50px; */
|
||||
/* top: -200px; */
|
||||
}
|
||||
div {
|
||||
position:relative;
|
||||
top: 80px;
|
||||
left: 35%;
|
||||
width: 500px;
|
||||
border: 0ch;
|
||||
border: 4px solid aqua;
|
||||
background-color: rgba(255,255,255,0.6);
|
||||
}
|
||||
div h4 {
|
||||
text-align: center;
|
||||
font-size: 36px;
|
||||
font-style: inherit;
|
||||
font-family:Georgia, 'Times New Roman', Times, serif
|
||||
}
|
||||
td {
|
||||
position:relative;
|
||||
left: 15%;
|
||||
}
|
||||
input {
|
||||
width: 300px;
|
||||
height: 30px;
|
||||
border-radius: 18px;
|
||||
border-color: aqua;
|
||||
position: relative;
|
||||
/* left: 25%; */
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.tk input{
|
||||
position:relative;
|
||||
width: 15px;
|
||||
vertical-align: middle;
|
||||
/* height: 100%; */
|
||||
/* margin:0px; */
|
||||
/* line-height: 72px; */
|
||||
/* right: 50%; */
|
||||
}
|
||||
select {
|
||||
width: 300px;
|
||||
height: 30px;
|
||||
border-radius: 18px;
|
||||
border-color: aqua;
|
||||
position: relative;
|
||||
/* left: 25%; */
|
||||
margin: 20px;
|
||||
}
|
||||
a {
|
||||
position: relative;
|
||||
left: 20%;
|
||||
text-decoration: none;
|
||||
}
|
After Width: | Height: | Size: 783 KiB |
After Width: | Height: | Size: 373 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 401 B |
After Width: | Height: | Size: 588 KiB |
After Width: | Height: | Size: 1.5 MiB |
After Width: | Height: | Size: 645 KiB |
After Width: | Height: | Size: 708 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 7.0 MiB |
After Width: | Height: | Size: 2.7 MiB |
After Width: | Height: | Size: 3.3 MiB |
After Width: | Height: | Size: 6.5 MiB |
After Width: | Height: | Size: 3.3 MiB |
After Width: | Height: | Size: 724 B |
After Width: | Height: | Size: 388 KiB |
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
{% load static %}
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>注册页面</title>
|
||||
<link rel="stylesheet" href="{% static 'css/zhuce.css' %}">
|
||||
</head>
|
||||
<body>
|
||||
<form method="post">
|
||||
{%csrf_token%}
|
||||
<div>
|
||||
<h4>启航题库</h4>
|
||||
<table width="500">
|
||||
<!-- 第一行 -->
|
||||
<!-- <tr>
|
||||
<td>
|
||||
我是:
|
||||
</td>
|
||||
<td>
|
||||
<label><input type="radio" name="id"><img src="../images/men.jpg" width="25">老师</label>
|
||||
<label><input type="radio" name="id"> <img src="../images/women.jpg" width="25" >学生</label>
|
||||
</td>
|
||||
</tr> -->
|
||||
<!-- 第二行 -->
|
||||
<tr>
|
||||
<td>
|
||||
<select name="identity" required="required">
|
||||
<option>我的身份</option>
|
||||
<option name=identity" value="老师">老师</option>
|
||||
<option name="identity" value="学生">学生</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 第三行 -->
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" name="name" required="required" placeholder="我的姓名">
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 第四行 -->
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" name="id_number" required="required" placeholder="学号or工号">
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 第六行 -->
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" name="phone" required="required" placeholder="手机号码">
|
||||
|
||||
</td>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" name="username" required="required" placeholder="用户名">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="password" name="password" required="required" placeholder="密码">
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<!-- 第八行 -->
|
||||
<br>
|
||||
{% if error_msg %}<p><strong>{{ error_msg }}</strong></p>{% endif %}
|
||||
<br>
|
||||
<tr>
|
||||
<td class>
|
||||
<input type="submit" value="注册">
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 第九行 -->
|
||||
<tr>
|
||||
<td class="tk">
|
||||
<input type="radio"> 我同意注册条款和会员加入标准
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 第十行 -->
|
||||
<tr>
|
||||
<td >
|
||||
<a href="#"> 我是会员,立即登录</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
@ -0,0 +1,21 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
app_name = 'login'
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
path('register/', views.register),
|
||||
|
||||
path('login/', views.login, name='login'),
|
||||
|
||||
path('dologin/', views.dologin, name='dologin'),
|
||||
|
||||
path('logout/', views.logout, name='logout'),
|
||||
|
||||
path('captcha_img/', views.captcha_img, name='captcha_img'),
|
||||
|
||||
]
|
||||
|
@ -0,0 +1,140 @@
|
||||
from django.shortcuts import render, HttpResponse, redirect
|
||||
from pymysql import IntegrityError
|
||||
from io import BytesIO
|
||||
from login.models import UserInfo
|
||||
from django.core.paginator import Paginator, Page
|
||||
from django.conf import settings
|
||||
from login.common import captcha
|
||||
|
||||
|
||||
def home(request):
|
||||
return render(request, 'home.html')
|
||||
|
||||
|
||||
def register(request):
|
||||
"""
|
||||
注册模块
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
if request.method == 'GET':
|
||||
return render(request, 'zhuce.html')
|
||||
|
||||
# 获取用户提交的数据
|
||||
try:
|
||||
identity = request.POST.get("identity")
|
||||
name = request.POST.get("name")
|
||||
id_number = request.POST.get("id_number")
|
||||
phone = request.POST.get("phone")
|
||||
username = request.POST.get("username")
|
||||
password = request.POST.get("password")
|
||||
|
||||
# 添加到数据库
|
||||
UserInfo.objects.create(identity=identity, name=name, id_number=id_number, phone=phone, username=username, password=password)
|
||||
|
||||
# 一个跳转
|
||||
#
|
||||
#
|
||||
# 之后跳转至登录界面
|
||||
#
|
||||
return redirect('login:login')
|
||||
except IntegrityError:
|
||||
error_msg = '该手机号或用户名已被注册!'
|
||||
return render(request, 'zhuce.html', {'error_msg': error_msg} )
|
||||
|
||||
|
||||
def server_error(request):
|
||||
error_msg = '该手机号或用户名已被注册!'
|
||||
return HttpResponse("asedfsdf")
|
||||
|
||||
|
||||
def login00(request):
|
||||
|
||||
if request.method == 'GET':
|
||||
return render(request, 'login.html')
|
||||
|
||||
error_msg = ""
|
||||
user = request.POST.get('email')
|
||||
pwd = request.POST.get('password')
|
||||
|
||||
temp_RawQuerySet = UserInfo.objects.raw('select * from app02_userfo')
|
||||
|
||||
for temp in temp_RawQuerySet:
|
||||
if temp.username == user and temp.password == pwd:
|
||||
if temp.identity == '老师':
|
||||
return redirect('http://www.baidu.com')
|
||||
else:
|
||||
return redirect('http://www.baidu.com')
|
||||
else:
|
||||
# 用户密码不匹配
|
||||
error_msg = '用户名或密码错误'
|
||||
return render(request, 'login.html', {'error_msg': error_msg})
|
||||
|
||||
|
||||
def login(request):
|
||||
# 从cookie中获取用户名和密码
|
||||
username = request.COOKIES.get('username')
|
||||
password = request.get_signed_cookie('pwd', None, salt='pwdsalt')
|
||||
if username and password:
|
||||
return render(request, 'login.html', {'username': username, 'pwd': password})
|
||||
else:
|
||||
return render(request, 'login.html')
|
||||
|
||||
|
||||
def dologin(request):
|
||||
|
||||
# 获取表单中提交的验证码
|
||||
check_code = request.POST.get('check_code')
|
||||
print(check_code)
|
||||
# 获取session会话中保存的code
|
||||
session_checkcode = request.session.get('check_code')
|
||||
if check_code and check_code.lower() == session_checkcode.lower():
|
||||
# 从登录表单中获取用户名和密码及是否勾选了记住密码
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('password')
|
||||
rember = request.POST.get('rember')
|
||||
response = HttpResponse()
|
||||
|
||||
temp_RawQuerySet = UserInfo.objects.raw('select * from login_userinfo')
|
||||
|
||||
for temp in temp_RawQuerySet:
|
||||
if temp.username == username and temp.password == password:
|
||||
|
||||
if rember == 'rember':
|
||||
# 勾选了记住用户名和密码
|
||||
# 将用户名和密码保存到cookie中
|
||||
response.set_cookie('username', username, max_age=3 * 24 * 3600)
|
||||
response.set_signed_cookie('pwd', password, salt='pwdsalt', max_age=3 * 24 * 3600)
|
||||
else:
|
||||
# 删除cookie中的之前保存用户名和密码
|
||||
response.delete_cookie('username')
|
||||
response.delete_cookie('pwd')
|
||||
|
||||
if temp.identity == '老师':
|
||||
return render(request, 'teacher_client.html', {'username': temp.username})
|
||||
else:
|
||||
return redirect('http://www.baidu.com')
|
||||
|
||||
# 用户密码不匹配
|
||||
response.delete_cookie('username')
|
||||
response.delete_cookie('pwd')
|
||||
error_msg = '用户名或密码错误'
|
||||
return render(request, 'login.html', {'error_msg1': error_msg})
|
||||
else:
|
||||
error_msg = '验证码错误'
|
||||
return render(request, 'login.html', {'error_msg': error_msg})
|
||||
|
||||
|
||||
def logout(request):
|
||||
response = HttpResponse()
|
||||
response.delete_cookie('username')
|
||||
response.delete_cookie('pwd')
|
||||
return response and redirect('login:login')
|
||||
|
||||
|
||||
def captcha_img(request):
|
||||
stream = BytesIO()
|
||||
img, code = captcha.veri_code()
|
||||
img.save(stream, 'PNG')
|
||||
request.session['check_code'] = code
|
||||
return HttpResponse(stream.getvalue())
|
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'the_online_test_system.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class TeacherClientConfig(AppConfig):
|
||||
name = 'teacher_client'
|
@ -0,0 +1,20 @@
|
||||
# Generated by Django 3.1.4 on 2022-04-09 08:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='questionBank',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
],
|
||||
),
|
||||
]
|
@ -0,0 +1,6 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class questionBank(models.Model):
|
||||
"""用于存储题目数据"""
|
||||
|
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
@ -0,0 +1,12 @@
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
path('teacher_client/', views.teacher_client),
|
||||
|
||||
|
||||
]
|
@ -0,0 +1,7 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
|
||||
def teacher_client(request):
|
||||
"""教师服务端"""
|
||||
if request.method == 'GET':
|
||||
return render(request, 'teacher_client.html')
|
@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for the_online_test_system project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'the_online_test_system.settings')
|
||||
|
||||
application = get_asgi_application()
|
@ -0,0 +1,134 @@
|
||||
"""
|
||||
Django settings for the_online_test_system project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 3.1.4.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/3.1/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/3.1/ref/settings/
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '%_iwhh8=4=smi^)&tzfdu%v9n=elm*0p21dpd-df8pcjift#ve'
|
||||
|
||||
# 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',
|
||||
'login.apps.LoginConfig',
|
||||
'teacher_client.apps.TeacherClientConfig'
|
||||
]
|
||||
|
||||
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 = 'the_online_test_system.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': []
|
||||
,
|
||||
'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 = 'the_online_test_system.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
||||
|
||||
# DATABASES = {
|
||||
# 'default': {
|
||||
# 'ENGINE': 'django.db.backends.sqlite3',
|
||||
# 'NAME': BASE_DIR / 'db.sqlite3',
|
||||
# }
|
||||
# }
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': 'superstar_1', # 数据库的名字
|
||||
'USER': 'root', # MySQL账户名
|
||||
'PASSWORD': '1234', # MySQL密码
|
||||
'HOST': 'localhost', # 哪台机器上的MySQL
|
||||
'PORT': 3306, # 端口
|
||||
}
|
||||
}
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/3.1/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/3.1/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'zh-Hans'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_L10N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/3.1/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
@ -0,0 +1,35 @@
|
||||
"""the_online_test_system URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/3.1/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
|
||||
from login import views
|
||||
import login
|
||||
|
||||
urlpatterns = [
|
||||
# admin后台界面
|
||||
path('admin/', admin.site.urls),
|
||||
|
||||
# 主界面home
|
||||
path('', views.login),
|
||||
|
||||
# 注册界面
|
||||
path('', include("login.urls")),
|
||||
|
||||
# 教师端口
|
||||
path('', include("teacher_client.urls")),
|
||||
]
|
||||
|
||||
handler500 = login.views.server_error
|
@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for the_online_test_system project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'the_online_test_system.settings')
|
||||
|
||||
application = get_wsgi_application()
|