Django+xadmin打造在线考试系统(四)

文章同步发于公众号:1024程序开发者社区(cxkfzsq1024)

公众号中回复“在线考试”获取开源代码链接

上篇文章介绍了页面组成路由关系和xadmin建立后台管理两部分内容,本次介绍django数据库操作和试题界面设计三部分内容。

/1/django数据库操作

在实际生产环境,Django是不可能使用自带SQLite这种轻量级的基于文件的数据库作为生产数据库。一般较多的会选择MySQL。

《Django+xadmin打造在线考试系统(四)》 image

配合MySQL,使用navicat进行可视化操作。

《Django+xadmin打造在线考试系统(四)》 image

建立数据库后,pip安装pymysql,在seting.py中进行设置,就可以使用mysql数据库了。

注意:使用utf-8编码,否则中文数据会出现乱码。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testonlinebc1',
        'USER': 'root',          #账号
        'PASSWORD': '',      #密码 
        'HOST': '127.0.0.1',    #IP 
        'PORT': '3306',
    }
}

(1)新增数据,通过save提交到数据库

user_score.total = temp_score
user_score.save()

(2)查询数据,get(条件)查询一定条件下的数据,返回object

user_info = UserProfile.objects.get(username=request.user)

通过filter查询

question_id_list = PaperCache.objects.filter(user=request.user)

输入参数:
get的参数只能是model中定义的哪些字段,只支持严格匹配;
filter的参数可以是字段也可以是扩展的where查询关键字,如in,like。
返回值:
get返回值是一个定义的model对象;
filter返回值是一个新的QuerySet对象,然后可以对QuerySet在进行查询返回新的QuerySet对象,支持链式操作,QuerySet一个集合对象,可使用迭代或者遍历,切片等,但是不等于list类型(是一个object对象集合)。

papers = Paper.objects.filter(paper_name_id=paper_id)  # 可迭代 question_id_list = []
for paper in papers:
    question = Question.objects.get(pk=paper.question_id)
    question_id_list.append(question.id)

(3)删除

question_id_list.delete()

(4)修改就是查询对应数据,进行修改并存储。

/2/试题界面设计

试题界设计是在线考试系统最核心的功能,主要分试题的获取,提交和页面显示三个部分。
随机考试的代码在views.py为:
get()函数首先实现根据题型随机抽题,将抽取的题目ID存在Paper_Cache数据表中,并将题目从question数据表中读取出来存在question_list中,最后通过render()将数据渲染到test_paper.html上。
post()函数根据试题类型读取用户提交的答案,并对比答案进行判卷,最后将考试成绩存在user_score中,将错题存在wrong_question列表中,最后通过render()将数据渲染到score.html上。

class SelectView(View): 
def get(self, request): if request.user.is_authenticated: 
question_list = []
seq1 = [i for i in range(1, 4)]
            seq2 = [i for i in range(4, 7)]
            seq3 = [i for i in range(7, 10)]
            question_id_list1 = random.sample(seq1,2 )
            question_id_list2 = random.sample(seq2,2 )
            question_id_list3 = random.sample(seq3,2 )
            question_id_list1.extend(question_id_list2)
            question_id_list1.extend(question_id_list3) for question_id in question_id_list1: question = Question.objects.get(id=question_id)
                question_list.append(question)
                Paper_Cache = PaperCache()
                Paper_Cache.question = question_id
                Paper_Cache.user = request.user
                Paper_Cache.add_time = datetime.now()
                Paper_Cache.save()
  title = "考试"
  question_now = tuple(question_list) # 题目元组 question_count = len(question_now) # 题目数 return render(request, "test_paper.html", {"question": question_now,"question_count": question_count, "title": title,}) else: return render(request, "login.html", {"msg": u'为保证考试客观公正,考题不对未登录用户开放'}) def post(self, request):
  question_id_list = PaperCache.objects.filter(user=request.user)
        user_info = UserProfile.objects.get(username=request.user)
        title = "考试"
  user_score = UserScore()
  user_score.user = request.user
  user_score.add_time = datetime.now()
        user_score.leibie = user_info.leibie
        user_score.nickname = user_info.nickname
        user_score.zhiwu = user_info.zhiwu
        user_score.danwei = user_info.danwei
  temp_score = 0
  user_score.paper = PaperList.objects.get(pk=3)
        wrong_question = [] for i in question_id_list:
  temp_question = Question.objects.get(pk=i.question) if temp_question.questionType == 'mxz': a = str(i.question)+'_1' b = str(i.question)+'_2' c = str(i.question)+'_3' d = str(i.question)+'_4' e = str(i.question)+'_5' f = str(i.question)+'_6' user_ans1 = request.POST.get(a, "") # 找对应题号的答案 user_ans2 = request.POST.get(b, "") # 找对应题号的答案 user_ans3 = request.POST.get(c, "") # 找对应题号的答案 user_ans4 = request.POST.get(d, "") # 找对应题号的答案 user_ans5 = request.POST.get(e, "") # 找对应题号的答案 user_ans6 = request.POST.get(f, "") # 找对应题号的答案 user_ans_final = user_ans1+user_ans2+user_ans3+user_ans4+user_ans5+user_ans6 a = temp_question.answer if temp_question.answer == user_ans_final: temp_score += temp_question.score else: question = Question.objects.get(id=i.question)
                    wrong_question.append(question) else: user_ans = request.POST.get(str(i.question), "")#找对应题号的答案
  if temp_question.answer == user_ans: temp_score += temp_question.score else: question = Question.objects.get(id=i.question)
                    wrong_question.append(question)
        wrong_question_now = tuple(wrong_question)
        wrong_question_count = len(wrong_question_now)
        user_score.total = temp_score
        user_score.save()
        question_id_list.delete() return render(request, "score.html", {"score": user_score.total, "title": title,"wrong_question": wrong_question_now,"wrong_question_count":wrong_question_count }) 

test_paper.html主要包含三类题型的显示,倒计时和提交功能

{% if question_now.questionType == 'xz' %}
<from id="{{ question_now.id }}">
    <p>{{ forloop.counter }}.({{ "选择" }}) {{ question_now.content }}</p>  <input type="hidden" value="{{ question_now.id }}">
    <label><input name="{{ question_now.id }}" type="radio" value="A"/>{{ question_now.choice_a }}
    </label><br/>
    <label><input name="{{ question_now.id }}" type="radio" value="B"/>{{ question_now.choice_b }}
    </label><br/>
    <label><input name="{{ question_now.id }}" type="radio" value="C"/>{{ question_now.choice_c }}
    </label><br/>
    <label><input name="{{ question_now.id }}" type="radio" value="D"/>{{ question_now.choice_d }}
    </label><br/>
</from>
{% endif %}
{% if question_now.questionType == 'mxz' %}
    {% if question_now.choice_num == 4 %}
    <from id="{{ question_now.id }}" >
    <p>{{ forloop.counter }}.({{ "多选" }}) {{ question_now.content }}</p>
    <input type="hidden" value="{{ question_now.id }}">
    <label><input name="{{ question_now.id }}_1" type="checkbox" value="A" />{{ question_now.choice_a }}
    </label><br/>
    <label><input name="{{ question_now.id }}_2" type="checkbox" value="B"/>{{ question_now.choice_b }}
    </label><br/>
    <label><input name="{{ question_now.id }}_3" type="checkbox" value="C" />{{ question_now.choice_c }}
    </label><br/>
    <label><input name="{{ question_now.id }}_4" type="checkbox" value="D" />{{ question_now.choice_d }}
    </label><br/>
   </from>
  {% endif %} 

{% endif %}

{% if question_now.questionType == 'pd' %}
<from id="{{ question_now.id }}">

    <p>{{ forloop.counter }}.({{ "判断" }}) {{ question_now.content }}</p>
    <input type="hidden" value="{{ question_now.id }}">
    <label><input name="{{ question_now.id }}" type="radio" value="True"/>{{ "对" }}{# question_now.boolt #} </label><br/>
    <label><input name="{{ question_now.id }}" type="radio" value="False"/>{{ "错" }}{# question_now.boolf #} </label><br/> 

</from>

{% endif %}

通过type=radio和checkbox对单选和复选进行定义。

《Django+xadmin打造在线考试系统(四)》 image
《Django+xadmin打造在线考试系统(四)》 image
《Django+xadmin打造在线考试系统(四)》 image

倒计时模块采用jquery进行设计,倒计时结束,强制提交,效果如图:

《Django+xadmin打造在线考试系统(四)》 image

<script src="{% static 'js/jquery.min.js' %}"></script>
<script type="text/javascript">
        function submitForm() {
            document.getElementById("form1").submit();
        }
var intDiff = parseInt(1200); //倒计时总秒数量 function timer(intDiff) {
    window.setInterval(function() {
        var day = 0,
            hour = 0,
            minute = 0,
            second = 0; //时间默认值 if (intDiff > 0) {
            day = Math.floor(intDiff / (60 * 60 * 24));
            hour = Math.floor(intDiff / (60 * 60)) - (day * 24);
            minute = Math.floor(intDiff / 60) - (day * 24 * 60) - (hour * 60);
            second = Math.floor(intDiff) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60);
        }
        if (minute <= 9) minute = '0' + minute;
        if (second <= 9) second = '0' + second;
        $('#day_show').html(day + "天");
        $('#hour_show').html('<s id="h"></s>' + hour + '时');
        $('#minute_show').html('<s></s>' + minute + '分');
        $('#second_show').html('<s></s>' + second + '秒');
        intDiff--;
        if (intDiff ==0) {submitForm()}

    }, 1000);
}
$(function() {
    timer(intDiff); 
});
</script>

以上是建立在线考试系统的第四部分,本次内容就到这里,还请各路大神指点。

关注公众号,送海量学习资源,一起学django~

《Django+xadmin打造在线考试系统(四)》 image

1024程序开发者社区的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里就技术问题进行交流,还没有加入的小伙伴可以扫描下方“社区物业”二维码,让管理员帮忙拉进群,期待大家的加入。

《Django+xadmin打造在线考试系统(四)》 image

//猜你喜欢//

    原文作者:bc_zhang
    原文地址: https://www.jianshu.com/p/f72471a006db
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞