基于centos7+apache+django+MySQL+python的考试系统

1、环境

        1> CentOS Linux release 7.5.1804 (Core) 

        2>django 1.11.8

        3>mysql  Ver 15.1 Distrib 5.5.56-MariaDB

        4>apache Apache/2.4.6 (CentOS)

        5>python 2.7.5

2、背景

        由于工作需求,需要一个练习单选、多选、判断的考试系统,于是简单制作了一个。

3、步骤

    1> 安装相关软件

 

yum -y install epel-release #安装epel包

版本信息  

httpd.x86_64 0:2.4.6-80.el7.centos

 httpd-devel.x86_64 0:2.4.6-80.el7.centos

 mariadb-server.x86_64 1:5.5.56-2.el7

 mod_wsgi.x86_64 0:3.4-12.el7_0 

python-devel.x86_64 0:2.7.5-68.el7

 python2-pip.noarch 0:8.1.2-10.el7 

yum -y install httpd-devel python-devel httpd mariadb-server mod_wsgi python-pip #安装相关包

版本信息

django-1.11.8     pymysql-0.9.3              xlrd-1.2.0

安装django、pymysql、xlrd相关模块

2>创建简单项目测试环境

yum -y install httpd mariadb-server  #安装apache和MySQL

systemctl start httpd mariadb #启动apache和MySQL

systemctl stop firewalld  #关闭防火墙

setenforce 0  #关闭selinux

切换到/var/www/html 创建项目

django-admin startproject ch  #创建ch项目

切换到项目目录,并测试

python manage.py runserver   #运行项目,并在浏览器测试

如下图:

修改ch目录内的url文件,并创建views.py文件

如urls.py下图:

新建views.py文件,下图:

浏览器测试:

接下来测试apache环境

systemctl start httpd #启动apache,并在浏览器测试

修改apache配置文件

加载mod_wsgi模块(必须)

添加日志,方便查看错误(非必需)

配置文件末尾加入以上内容,其中ch是我的项目名称

192.168.80.147是我虚拟机的IP

浏览器测试报错,是配置文件settings.py文件的问题

debug改为false,allowed_hosts改为‘*’

浏览器测试,没有问题,接下来专门写程序就行了

3>考试系统编写

      1、模型创建(models.py)

#coding=utf-8
#-*- coding:utf-8 -*-
from django.db import models
# Create your models here.

class Question(models.Model):

    ANSWER=(
        ('A','A'),
        ('B','B'),
        ('C','C'),
        ('D','D'),
    )

    id = models.AutoField(primary_key=True)
    subject = models.CharField('科目', max_length=20,default='数据中心规划与实施')
    title = models.TextField('题目')
    optionA=models.CharField('A选项',max_length=300)
    optionB=models.CharField('B选项',max_length=300)
    optionC=models.CharField('C选项',max_length=300,null=True)
    optionD=models.CharField('D选项',max_length=300,null=True)
    answer=models.CharField('答案',max_length=10,choices=ANSWER)
    score=models.IntegerField('分数',default=1)
    classmodel=models.CharField('类型',max_length=30)
    unit=models.CharField('单元',max_length=300)

    class Meta:
        db_table='question'
        verbose_name='理论题库'
        verbose_name_plural=verbose_name
    def __str__(self):
        return '<%s:%s>'%(self.subject,self.title);

class Student(models.Model):
    sid = models.CharField(max_length=30)
    sname = models.CharField(max_length=30)

    class Meta:
        db_table='student'
        verbose_name='学生'
        verbose_name_plural=verbose_name
    def __str__(self):
        return '<%s:%s>'%(self.sid,self.sname);
        
class ErrorQuestion(models.Model):

    ANSWER=(
        ('A','A'),
        ('B','B'),
        ('C','C'),
        ('D','D'),
    )

    id = models.AutoField(primary_key=True)
    student=models.ForeignKey(Student,on_delete=models.CASCADE,default='')
    subject = models.CharField('科目', max_length=20,default='数据中心规划与实施')
    title = models.TextField('题目')
    optionA=models.CharField('A选项',max_length=300)
    optionB=models.CharField('B选项',max_length=300)
    optionC=models.CharField('C选项',max_length=300,null=True)
    optionD=models.CharField('D选项',max_length=300,null=True)
    answer=models.CharField('答案',max_length=10,choices=ANSWER)
    myanswer=models.CharField('我的答案',max_length=10)
    unit=models.CharField('单元',max_length=300)

    class Meta:
        db_table='errorquestion'
        verbose_name='错题本'
        verbose_name_plural=verbose_name
    def __str__(self):
        return '<%s:%s>'%(self.subject,self.title);

     2、注册文件(admin.py)

#coding=utf-8
#-*- coding:utf-8 -*-
from django.contrib import admin
from ch.models import ErrorQuestion,Question,Student
# Register your models here.

# 修改名称
admin.site.site_header='理论刷题系统后台'
admin.site.site_title='理论刷题系统'


@admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
    list_display = ('id','subject','title','optionA','optionB','optionC','optionD','answer','score')

@admin.register(ErrorQuestion)
class ErrorQuestionAdmin(admin.ModelAdmin):
    list_display = ('id','subject','title','optionA','optionB','optionC','optionD','answer','myanswer')

@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    list_display = ('sid','sname')

3、初始化文件(__init__.py)

import pymysql
pymysql.install_as_MySQLdb()

4、视图函数文件(views.py)

#coding=utf-8
#-*- coding:utf-8 -*-
from django.shortcuts import render,redirect
from django.http import HttpResponse
from . import models
from .islogin import islogin
# Create your views here.

def index(request):
    if request.method=='POST':
        stu_id = request.POST.get('stu_id')
        print('10行',stu_id)
        sid = models.Student.objects.get(sid=stu_id)
        if sid:
            red = render(request,'index.html',{'sid':sid})
            # 记住用户名
            red.set_cookie('uname', stu_id)
            request.session['stu_id'] = sid.id
            print('sid.id',sid.id)
            request.session['stu_name'] = sid.sname
            return red
            # return render(request,'index.html',{'sid':sid})
        else:
            return render(request,'login.html',{'msg':'请输入正确的学号'})
    return render(request,'login.html')

@islogin
def startExam(request):
    sname = request.session.get('stu_name')
    unit = request.GET['unit']
    paper=models.Question.objects.filter(unit=unit)
    return render(request,'exam.html',{'paper':paper,'subject':unit,'m':len(paper),'sname':sname})

@islogin
def calGrade(request):
    if request.method=='POST':
        subject1 = request.POST.get('subject')
        sname = request.session.get('stu_name')
        sid = request.session.get('stu_id')
        stu_id = models.Student.objects.get(id=sid).sid
        models.ErrorQuestion.objects.filter(student_id=sid).delete()
    #     # 计算该门考试的学生成绩
        question= models.Question.objects.filter(unit=subject1).values()
        sub = 0
        mygrade=0#初始化一个成绩为0
        for p in question:
            qId=str(p['id'])#int 转 string,通过pid找到题号
            myans=request.POST.getlist(qId)#通过 qid 得到学生关于该题的作答
            er = ''
            # print(myans)
            for i in myans:
                er += i
            okans=p['answer']#得到正确答案
            # print(okans)
            if er==okans:#判断学生作答与正确答案是否一致
                mygrade+=p['score']#若一致,得到该题的分数,累加mygrade变量
            elif er == '':
                pass
            else:
                sub += 1
                if p['optionC']:
        #     #向errorquestion表中插入数据
                    models.ErrorQuestion.objects.create(subject=subject1,student_id=sid,title=p['title'],optionA=p['optionA'],optionB=p['optionB'],optionC=p['optionC'],optionD=p['optionD'],answer=p['answer'],myanswer=er,unit=p['unit'])
                else:
                    models.ErrorQuestion.objects.create(subject=subject1,student_id=sid,title=p['title'],optionA=p['optionA'],optionB=p['optionB'],answer=p['answer'],myanswer=er,unit=p['unit'])

        paper=models.ErrorQuestion.objects.filter(unit=subject1,student_id=sid)
    return render(request,'errorq.html',{'paper':paper,'subject':subject1,'mygrade':mygrade,'sub':sub,'sname':sname,'stu_id':stu_id})

5、路由文件(urls.py)

#coding=utf-8
#-*- coding:utf-8 -*-
from django.conf.urls import url
from django.contrib import admin
from . import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$',views.index),
    url(r'^startExam',views.startExam),
    url(r'^calGrade',views.calGrade),
]

6、装饰器文件(islogin.py)

#coding=utf-8
from django.http import HttpResponseRedirect

#如果登录则转到登录页面
def islogin(func):
    def login_fun(request,*args,**kwargs):
        if request.session.get('stu_id'):
            return func(request,*args,**kwargs)
        else:
            red = HttpResponseRedirect('/')
            red.set_cookie('url',request.get_full_path)
            return red
    return login_fun

7、将表格中的文件导入到数据库(extransfer.py),共计19单元,表格内容如下:

#coding=utf-8
#-*- coding:utf-8 -*-
import pymysql
import xlrd
import sys
reload(sys) 
sys.setdefaultencoding('utf-8')
# 创建连接
conn = pymysql.connect(   # 打开数据库连接
    host='127.0.0.1',     # IP
    port=3306,            # 端口
    user='root',          # 数据库用户名
    password="123456",# 密码
    database='ch',       # 要连那个库
    charset='utf8')       # 设置字符集

# 拿到游标
cur = conn.cursor()  # 默认返回的是元祖   conn.cursor(pymysql.cursors.DictCursor)  返回字典
cur.execute('use bwll;') # 进入数据库

for i in range(1,20):
    # 打开Excel文件
    bok = xlrd.open_workbook('../static/examunit/第{}单元.xlsx'.format(i))
    sht=bok.sheets()[0]

    for m in range(1,100):
        try:
            row1 = sht.row_values(m)
        except:
            print('break',m)
            break
        else:
            row2= row1[2].replace('(网工)','')
            row3= row2.replace('(数据中心)','')   
            row= row3.replace('()','')
        
        if row1[1][0] == '1':
            n = "insert into question(subject,title,optionA,optionB,optionC,optionD,answer,score,classmodel,unit) values('{}','{}','{}','{}','{}','{}','{}','{}','{}','{}');".format('数据中心规划与实施',row,row1[3],row1[4],row1[5],row1[6],row1[9],'3','单选题','第{}单元'.format(i))
        elif row1[1][0] == '2':
            n = "insert into question(subject,title,optionA,optionB,optionC,optionD,answer,score,classmodel,unit) values('{}','{}','{}','{}','{}','{}','{}','{}','{}','{}');".format('数据中心规划与实施',row,row1[3],row1[4],row1[5],row1[6],row1[9],'2','多选题','第{}单元'.format(i))
        else:
            n = "insert into question(subject,title,optionA,optionB,answer,score,classmodel,unit) values('{}','{}','{}','{}','{}','{}','{}','{}');".format('数据中心规划与实施',row,'正确','错误',row1[9],'2','判断题','第{}单元'.format(i))


    	# print(m)
        cur.execute(n)
        conn.commit()
cur.execute("select * from question;")
# content = cur.fetchmany(2)  # 返回2条数据 (('information_schema',), ('db1',))
content = cur.fetchall()    # 返回所有数据
for i in content:
	print(i)
cur.close()      # 关闭游标
conn.close()     # 关闭数据库连接

 

接下来是templates文件

errorq.html #显示错题的页面

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>网工理论刷题系统</title>

<style>
.hasBeenAnswer {
	background: #5d9cec;
	color:#fff;
}
</style>

</head>
<body>

<nav class="navbar navbar-expand-sm bg-light navbar-light ">

            <a class="nav-link"><h3>当前科目:{{ subject }}</h3></a>

</nav>
<p>欢迎{{sname}}登录</p>
<div class="main">
	<!--nr start-->
	<div class="test_main">
		<div class="nr_left">
			<div class="test">
				<form action="/" method="post">
				{%csrf_token%}
                <input type="hidden" name="stu_id" value="{{ stu_id }}">
                <input type="hidden" name="sname" value="{{ sname }}">
                <input type="hidden" name="subject" value="{{ subject }}">
					<div class="test_title">
						<font><input type="submit" name="tijiao" value="返回首页"></font>
					</div>

						<div class="test_content">
							<div class="test_content_title">
								<!-- <h2>单选题</h2> -->
								<p>
									<span>共错了</span><i class="content_lit">{{sub}}</i><span>题,</span>
                                    <span>成绩</span><i class="content_fs">{{mygrade}}</i><span>分</span>
								</p>
							</div>
						</div>
						<div class="test_content_nr">
							<ul>
                                {% for test in paper %}
                                       <li id="{{ forloop.counter }}">
                                        <div class="test_content_nr_tt">
                                            <font>{{ test.title }}</font>
                                            <p>正确答案:{{test.answer}} 我的答案:{{test.myanswer}}</p>

										</div>
                                       <div class="test_content_nr_main">
                                       	{%if test.optionC is wu%}
                                       	A.<p class="ue" style="display: inline;">{{ test.optionA }}</p><br>
                                       	B.<p class="ue" style="display: inline;">{{ test.optionB }}</p><br>
                                       	{%else%}
                                       	A.<p class="ue" style="display: inline;">{{ test.optionA }}</p><br>
                                       	B.<p class="ue" style="display: inline;">{{ test.optionB }}</p><br>
                                       	C.<p class="ue" style="display: inline;">{{ test.optionC }}</p><br>
                                       	D.<p class="ue" style="display: inline;">{{ test.optionD }}</p><br>
                                       	{%endif%}
										</div>
                                        </li>
                                {% endfor %}
							</ul>
						</div>
				</form>
			</div>
		</div>

	</div>
	<!--nr end-->
	<div class="foot"></div>
</div>

</body>
</html>

exam.html #考试页面

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>网工理论刷题系统</title>

<style>
.hasBeenAnswer {
	background: #5d9cec;
	color:#fff;
}
</style>

</head>
<body>

<nav class="navbar navbar-expand-sm bg-light navbar-light ">

            <a class="nav-link"><h3>当前科目:{{ subject }}</h3></a>

</nav>
<div class="main">
	<!--nr start-->
	<p>欢迎{{sname}}登录</p>
	<div class="test_main">
		<div class="nr_left">
			<div class="test">
				<form action="/calGrade/" method="post">
				{%csrf_token%}
                <input type="hidden" name="stu_id" value="{{ student.id }}">
                <input type="hidden" name="subject" value="{{ subject }}">
					<div class="test_title">
						<font><input type="submit" name="tijiao" value="交卷"></font>
					</div>

						<div class="test_content">
							<div class="test_content_title">
								<!-- <h2>单选题</h2> -->
								<p>
									<span>共</span><i class="content_lit">{{m}}</i><span>题,</span>
                                    <span>合计</span><i class="content_fs">100</i><span>分</span>
								</p>
							</div>
						</div>
						<div class="test_content_nr">
							<ul>
                                {% for test in paper %}
                                       <li id="{{ forloop.counter }}">
                                        <div class="test_content_nr_tt">
											<i>{{ forloop.counter}}、</i><span>({{ test.score }}分)</span>
                                            <font>{{ test.title }}</font>

										</div>
										{% if test.classmodel == '单选题'%}
                                       <div class="test_content_nr_main">
											<ul>
													<li class="option">
															<input type="radio" class="radioOrCheck" name="{{ test.id }}" value="A"/>
														<label>
															A.<p class="ue" style="display: inline;">{{ test.optionA }}</p>
														</label>
													</li>

													<li class="option">
															<input type="radio" class="radioOrCheck" name="{{ test.id }}" value="B"/>
														<label>
															B.<p class="ue" style="display: inline;">{{ test.optionB }}</p>
														</label>
													</li>

													<li class="option">
															<input type="radio" class="radioOrCheck" name="{{ test.id }}" value="C"/>
														<label>
															C.<p class="ue" style="display: inline;">{{ test.optionC }}</p>
														</label>
													</li>

													<li class="option">
															<input type="radio" class="radioOrCheck" name="{{ test.id }}" value="D"/>
														<label>
															D.<p class="ue" style="display: inline;">{{ test.optionD }}</p>
														</label>
													</li>
											</ul>
										</div>
                                        {% elif test.classmodel == '多选题'%}
                                       <div class="test_content_nr_main">
											<ul>
													<li class="option">
															<input type="checkbox" class="radioOrCheck" name="{{ test.id }}" value="A"/>
														<label>
															A.<p class="ue" style="display: inline;">{{ test.optionA }}</p>
														</label>
													</li>

													<li class="option">
															<input type="checkbox" class="radioOrCheck" name="{{ test.id }}" value="B"/>
														<label>
															B.<p class="ue" style="display: inline;">{{ test.optionB }}</p>
														</label>
													</li>

													<li class="option">
															<input type="checkbox" class="radioOrCheck" name="{{ test.id }}" value="C"/>
														<label>
															C.<p class="ue" style="display: inline;">{{ test.optionC }}</p>
														</label>
													</li>

													<li class="option">
															<input type="checkbox" class="radioOrCheck" name="{{ test.id }}" value="D"/>
														<label>
															D.<p class="ue" style="display: inline;">{{ test.optionD }}</p>
														</label>
													</li>
											</ul>
										</div>
                                        {% else %}
                                       <div class="test_content_nr_main">
											<ul>
													<li class="option">
															<input type="radio" class="radioOrCheck" name="{{ test.id }}" value="A"/>
														<label>
															A.<p class="ue" style="display: inline;">{{ test.optionA }}</p>
														</label>
													</li>

													<li class="option">
															<input type="radio" class="radioOrCheck" name="{{ test.id }}" value="B"/>
														<label>
															B.<p class="ue" style="display: inline;">{{ test.optionB }}</p>
														</label>
													</li>
											</ul>
										</div>
                                        </li>
                                        {% endif %}
                                {% endfor %}
							</ul>
						</div>
				</form>
			</div>
		</div>

	</div>
	<!--nr end-->
	<div class="foot"></div>
</div>

</body>
</html>

index.html #首页,显示考试单元

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>网工理论刷题系统</title>
    <style type="text/css">
      a{ text-decoration:none} 
      a:hover{ text-decoration:none}
    </style>
</head>
<body>

<nav class="navbar navbar-expand-sm bg-light navbar-light ">
    <ul class="navbar-nav">
            <h3>数据中心规划与实施</h3>

            <p>欢迎{{sid.sname}}登录</p>

        <li>
            <p><a href="/startExam/?unit=第1单元">第一单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第2单元">第二单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第3单元">第三单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第4单元">第四单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第5单元">第五单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第6单元">第六单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第7单元">第七单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第8单元">第八单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第9单元">第九单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第10单元">第十单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第11单元">第十一单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第12单元">第十二单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第13单元">第十三单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第14单元">第十四单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第15单元">第十五单元</a></p>
        </li>
                <li>
            <p><a href="/startExam/?unit=第16单元">第十六单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第17单元">第十七单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第18单元">第十八单元</a></p>
        </li>
        <li>
            <p><a href="/startExam/?unit=第19单元">第十九单元</a></p>
        </li>

    </ul>


</body>

</html>

login.html #登陆页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>网工理论刷题系统登录</title>
</head>
<body>
    <form action="/" method="post">
        {%csrf_token%}
        <input type="text" name="stu_id" placeholder="请输入学号">
        <input type="submit" name="login" value="登录"><br>
        {{msg}}
    </form>


</body>
</html>

成功了

 

这一个是整体的,稍后有时间我会上一个在阿里服务器部署的相关文章

 

登陆账号   4100105207     网址:http://47.95.212.226/

 

 

 

未完待续----------------------------------------------------------------------------------需要上班


 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在CentOS 7上搭建一个简单的PHP + Apache + MySQL站点,可以按照以下步骤操作: 1. 安装必要的软件包 首先,需要安装PHP、ApacheMySQL的相关软件包,可以使用以下命令进行安装: ``` sudo yum install httpd mariadb mariadb-server php php-mysql ``` 2. 启动ApacheMySQL服务 安装完成后,需要启动ApacheMySQL服务,并将它们设置为系统启动时自动启动。可以使用以下命令: ``` sudo systemctl start httpd sudo systemctl enable httpd sudo systemctl start mariadb sudo systemctl enable mariadb ``` 3. 配置MySQL 接下来,需要设置MySQL的root密码并进行一些基本的安全设置。可以使用以下命令: ``` sudo mysql_secure_installation ``` 按照提示一步步进行设置即可。 4. 创建数据库 然后,需要创建一个新的MySQL数据库和用户,以便在PHP应用程序中使用。可以使用以下命令: ``` sudo mysql -u root -p CREATE DATABASE mydatabase; CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'localhost'; FLUSH PRIVILEGES; exit; ``` 5. 创建简单的PHP页面 现在,可以创建一个简单的PHP页面来测试站点是否正常工作。可以在`/var/www/html/`目录中创建一个名为`index.php`的文件,包含以下内容: ``` <?php $servername = "localhost"; $username = "myuser"; $password = "mypassword"; $dbname = "mydatabase"; // 创建连接 $conn = new mysqli($servername, $username, $password, $dbname); // 检查连接是否成功 if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } echo "Connected successfully"; ?> ``` 6. 访问站点 现在,可以通过浏览器访问站点,输入服务器的IP地址或域名,即可看到PHP页面的输出。 以上就是基于CentOS 7搭建简单的PHP + Apache + MySQL站点的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值