# Create your models here. class Subject(models.Model): stem = models.CharField(max_length=1024, verbose_name='题干内容', blank=False, null=False) type = models.IntegerField(choices=Type, verbose_name='题目类型,单选还是多选') explain = models.CharField(max_length=512, verbose_name='题目答案解析', blank=False, null=False) class Meta: db_table = 'subject' verbose_name = '题干表' class Options(models.Model): options = models.IntegerField(choices=Option, verbose_name='选项ABCDEFGH') content = models.CharField(max_length=256, verbose_name='选项内容') subject = models.ForeignKey('Subject') class Meta: db_table = 'options' verbose_name = '选项表' unique_together = ('subject', 'content') ordering = ['options'] class Answer(models.Model): options = models.IntegerField(choices=Option, verbose_name='选项ABCDEFGH') subject = models.ForeignKey('Subject') class Meta: db_table = 'answer' verbose_name = '答案表' unique_together = ('subject', 'options') ordering = ['options']

这里题目类型对应的类型为choices即数字0对应单选数字1对应多选

选项表也是12345678分别对应选项ABCDEFGH

注意运行数据迁移命令的路径是在项目文件夹下

D:\health>python manage.py makemigrations subject
D:\health>python manage.py migrate subject

  登录数据库查看创建的表

E , 感觉功能、运动功能、联络功能系统 人的心理现象包括心理过程和个性心理。 心理过程包括认识教程、情结与情感过程、意志教程三个相互联系的方面。 个性心理特征包括人的能力、气质、性格。具体表现在人的个性倾向性、个性心理特征和自我意识三个方面

  首先插入题目和解析

mysql> insert into subject values(null,'人类心理现象包括',0,'人的心理现象包括心理过程和个性心理。 心理过程包括认识教程、情结与情感过程、意志教程三个相互联系的方面。 个性心理特征包括人的能力、气质、性格。具 体表现在人的个性倾向性、个性心理特征和自我意识三个方面');

  id自增,题目为单选题

mysql> insert into options values(null,1,'心理活动过程',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into options values(null,2,'个性心理特征',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into options values(null,3,'认知,情感和意志力',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into options values(null,4,'心理活动过程和个性心理特征',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into options values(null,5,'感觉功能、运动功能、联络功能系统',1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into answer values(null,4,1);
Query OK, 1 row affected (0.00 sec)

  查看数据库

   三,在web页面展示数据

  ①设置路由

{% for one in object_list %} {# 显示题目题干 forloop.counter为显示序号 #} <p>{{ forloop.counter }}, {{ one.stem }}</p> {# 显示选项以及对应选项的内容get_options_display为把选项1234显示成ABCD#} {% for options in one.options_set.all %} {{ options.get_options_display }}, {{ options.content }} </br> {% endfor %} {# 显示答案get_options_display为把选项1234显示成ABCD#} {% for answer in one.answer_set.all %} {{ answer.get_options_display }} {% endfor %} {% endfor %} </body> </html>

  web页面查看

   把答案和解析做成隐藏然后使用按键显示

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>健康管理师练习题</title>
</head>
{#    遍历数据库提取所有题目#}
    {% for one in object_list %}
{#        显示题目题干 forloop.counter为显示序号 #}
        <p>{{ forloop.counter }}, {{ one.stem }}</p>
{#        显示选项以及对应选项的内容get_options_display为把选项1234显示成ABCD#}
        {% for options in one.options_set.all %}
            {{ options.get_options_display }}, {{ options.content }} </br>
        {% endfor %}
{#        显示答案get_options_display为把选项1234显示成ABCD#}
        <p id="{{ one.id }}id" hidden>
        {% for answer in one.answer_set.all %}
            {{ answer.get_options_display }}
        {% endfor %}
        <input type = 'button' onclick=showp("{{ one.id }}id") value='答案'/>
        <p id="{{ one.id }}explain" hidden>{{ one.explain }}</p>
        <input type = 'button' onclick=showp("{{ one.id }}explain") value='解析'>
    {% endfor %}
<script>
    {#隐藏显示函数#}
    function showp(id){
        if (document.getElementById(id).style.display == 'inline') {
            document.getElementById(id).style.display = 'none';
        else {
            document.getElementById(id).style.display='inline';
</script>
</body>
</html>

  把答案和解析先隐藏,添加按钮,如果答案是隐藏的则点击按钮显示答案如果答案是显示的则点击按钮隐藏答案,解析也是如此

  这里把答案和解析包含在一个p标签内,id分别为使用one.id加字符串id拼接的即类似于1id 1explain的id这样保证每个p标签的id不重复并且在id内不会出现一些特殊字符导致id不可用的问题

   四,添加数据

class SubjectAddView(TemplateView):
    template_name = 'subject_add.html'
    def post(self, request):
        data = request.POST
        res = {'status': 0, 'msg': '添加成功'}
            subject = Subject()
            subject.stem = data.get('stem')
            subject.explain = data.get('explain')
            subject.type = data.get('type')
            print(data.getlist('option'))
            print(data.getlist('content'))
            print(data.getlist('explain'))
            print(data.getlist('answer'))
            subject.save()
            for one in data.getlist('option'):
                options = Options()
                options.subject_id = subject.id
                options.options = one
                options.content = data.getlist('content')[int(one)-1]
                options.save()
            for one in data.getlist('answer'):
                answer = Answer()
                answer.subject_id = subject.id
                answer.options = one
                answer.save()
        except Exception as e:
            print(e)
            res = {'status': 1, 'msg': '添加失败'}
        return JsonResponse(res)

   注意需要加载css js

<!DOCTYPE html>
<html lang="ch">
    <meta charset="UTF-8">
    <title>添加题目</title>
{#    <link href="/static/css/bootstrap.min.css" rel="stylesheet">#}
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
    <link href="/static/css/plugins/toastr/toastr.min.css" rel="stylesheet">
     <link href="/static/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">
{#    <link href="/static/css/animate.css" rel="stylesheet">#}
{#    <link href="/static/css/style.css" rel="stylesheet">#}
</head>
 <div class="ibox-content">
        <form id="submit_form" class="form-horizontal">
            {% csrf_token %}
            <div ><label class="col-sm-2 control-label">题目内容</label>
                <div class="col-sm-6"><input type="text"  maxlength="512" size="100" name="stem" required></div>
              <div ><label class="col-sm-2 control-label">题目解析</label>
{#                <div ><input type="text"maxlength="512" size="100" name="explain"></div>#}
                  <div> <textarea name="explain" cols="30" rows="10"> </textarea></div>
            题目类型:<input type="radio" name="type" value="0" checked/>  单选 <input type="radio" name="type" value="1" /> 多选 <br/>
            <div class="form-group"><label class="col-sm-2 control-label">选项</label>
                <div ><input type="checkbox"  name="option" value=1 checked > A <input type="text"  name="content" required></div>
                <div ><input type="checkbox"  name="option" value=2 checked > B <input type="text" class="" name="content"></div>
                <div ><input type="checkbox"  name="option" value=3 checked > C <input type="text" class="" name="content"></div>
                <div ><input type="checkbox"  name="option" value=4 checked > D <input type="text" class="" name="content"></div>
                <div ><input type="checkbox"  name="option" value=5> E <input type="text" class="" name="content"> </div>
                <div ><input type="checkbox"  name="option" value=6> F <input type="text" class="" name="content"> </div>
                <div ><input type="checkbox"  name="option" value=7> G <input type="text" class="f" name="content"> </div>
                <div ><input type="checkbox"  name="option" value=8> H <input type="text" class="" name="content"> </div>
                <div ><input type="checkbox"  name="option" value=9> I <input type="text" class="" name="content"> </div>
            <div class="form-group"><label class="col-sm-2 control-label">答案</label>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=1> A </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=2> B </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=3> C </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=4> D </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=5> E </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=6> F </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=7> G </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=8> H </div>
                <div class="col-sm-6"><input type="checkbox" class="" name="answer" value=9> I </div>
                <div class="">
{#                    <a class="btn btn-white" type="submit" href="javascript:history.back(-1)">取消</a>#}
                    <button class="btn btn-primary" type="submit">保存更改</button>
        </form>
    <script src="/static/js/jquery-3.1.1.min.js"></script>
    <script src="/static/js/bootstrap.min.js"></script>
    <script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
    <script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
    <script src="/static/js/plugins/validate/jquery.validate.js"></script>
    <script src="/static/js/plugins/validate/messages_zh.js"></script>
    <script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
    <script src="/static/js/inspinia.js"></script>
    <script src="/static/js/plugins/pace/pace.min.js"></script>
    <script>
        $(document).ready(function () {
            $("#submit_form").validate({
             submitHandler: function () {
                    var str = $('#submit_form').serialize();
                    $.post('{% url 'subject_add' %}', str, function (res) {
                        if (res.status == 0) {
                            swal({
                                title: res.msg,
                                type: 'success',
                                confirmButtonText: "确定"
                               function () {
                               window.location.href = '{% url 'index' %}';
                        } else {
                            swal({
                                title: res.msg,
                                type: 'error',
                                confirmButtonText: "确定"
    </script>
</body>
</html>

  首页增加一个跳转按钮至添加数据

class SubjectUpdateView(View):
    def get(self, request):
        return render(request, 'subject_update.html', {'subject_obj': Subject.objects.get(id=request.GET.get('id'))})
    def post(self, request):
        data = request.POST
        res = {'status': 0, 'msg': '修改成功'}
            subject = Subject.objects.get(id=data.get('uid'))
            print(subject)
            subject.stem = data.get('stem')
            subject.explain = data.get('explain')
            subject.type = data.get('type')
            print(data.getlist('option'))
            print(data.getlist('content'))
            print(data.getlist('answer'))
            subject.save()
            Options.objects.filter(subject_id=data.get('uid')).delete()
            for one in data.getlist('option'):
                options = Options()
                options.subject_id = subject.id
                options.options = one
                options.content = data.getlist('content')[int(one)-1]
                options.save()
            Answer.objects.filter(subject_id=data.get('uid')).delete()
            for one in data.getlist('answer'):
                answer = Answer()
                answer.subject_id = subject.id
                answer.options = one
                answer.save()
        except Exception as e:
            print(e)
            res = {'status': 1, 'msg': '修改失败'}
        return JsonResponse(res)

  更新数据和添加数据类似,不过是需要把原来数据库中已经存在的数据传递到页面,只修改需要修改的地方

<meta charset="UTF-8"> <title>添加题目</title> {# <link href="/static/css/bootstrap.min.css" rel="stylesheet">#} <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet"> <link href="/static/css/plugins/toastr/toastr.min.css" rel="stylesheet"> <link href="/static/css/plugins/sweetalert/sweetalert.css" rel="stylesheet"> {# <link href="/static/css/animate.css" rel="stylesheet">#} {# <link href="/static/css/style.css" rel="stylesheet">#} </head> <div class="ibox-content"> <form id="submit_form" class="form-horizontal"> {% csrf_token %} <h1> 更新题目 {{ subject_obj.id }}</h1> <div class="form-group"><label class="col-sm-2 control-label">题目内容</label> <div class="col-sm-6"><input type="text" class="form-control" maxlength="512" size="100" name="stem" value="{{ subject_obj.stem }}" required></div> <div class="hr-line-dashed"></div> <div class="form-group"><label class="col-sm-2 control-label">题目解析</label> {# <div class="col-sm-6"><input type="text" class="form-control" maxlength="512" size="100" name="explain" value="{{ subject_obj.explain }}"></div>#} <div> <textarea name="explain" cols="30" rows="10" >{{ subject_obj.explain }} </textarea></div> 题目类型:<input type="radio" name="type" value="0" checked/> 单选 <input type="radio" name="type" value="1" /> 多选 <br/> <div class="form-group"><label class="col-sm-2 control-label">选项</label> {% for options in subject_obj.options_set.all %} {% if options.options == 1 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=1 checked > A <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 2 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=2 checked > B <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 3 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=3 checked > C <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 4 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=4 checked > D <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 5 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=5 checked > E <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 6 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=6 checked > F <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 7 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=7 checked > G <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 8 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=8 checked > H <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% elif options.options == 9 %} <div class="col-sm-6"><input type="checkbox" class="form-control" name="option" value=9 checked > I <input type="text" class="form-control" name="content" value="{{ options.content }}"></div> {% endif %} {% endfor%} <div class="form-group"><label class="col-sm-2 control-label">答案</label> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=1> A </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=2> B </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=3> C </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=4> D </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=5> E </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=6> F </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=7> G </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=8> H </div> <div class="col-sm-6"><input type="checkbox" class="form-control" name="answer" value=9> I </div> <div class="hr-line-dashed"></div> <div class="form-group"> <div class="col-sm-4 col-sm-offset-2"> <input hidden value="{{ subject_obj.id }}" name="uid"> {# <a class="btn btn-white" type="submit" href="javascript:history.back(-1)">取消</a>#} <button class="btn btn-primary" type="submit">保存更改</button> </form> <script src="/static/js/jquery-3.1.1.min.js"></script> <script src="/static/js/bootstrap.min.js"></script> <script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script> <script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script> <script src="/static/js/plugins/validate/jquery.validate.js"></script> <script src="/static/js/plugins/validate/messages_zh.js"></script> <script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script> <script> $(document).ready(function () { $("#submit_form").validate({ rules: { name_cn: { required: true username: { required: true email: { required: true password: { required: true phone: { required: true, minlength:11 wechat: { required: true }, submitHandler: function () { var str = $('#submit_form').serialize(); $.post('{% url 'subject_update' %}', str, function (res) { if (res.status == 0) { swal({ title: res.msg, type: 'success', confirmButtonText: "确定" }, function () { window.location.href = '{% url 'index' %}'; } else { swal({ title: res.msg, type: 'error', confirmButtonText: "确定" </script> </body> </html>

  注意:本次有bug 例如更新数据只能更新原有选项一样多的数量选项,不能添加选项,答案没有按原有答案选中,需要重新选

  在首页添加一个更新数据的按键

  这里直接删除题目应该会同时清除选修班表和答案表,如果删除是出现外键关联错误导致无法删除可以,修改代码先删除选修表和答案表以后再删除题目表

 Options.objects.filter(subject_id=data.get('id')).delete()
 Answer.objects.filter(subject_id=data.get('id')).delete()
 Subject.objects.get(id=data.get('id')).delete()

  删除数据没有单独的模板,在index页面添加删除函数

function subject_delete(id) {
            if (confirm('确认删除吗?')) {
            {#alert(id)#}
                $.get("{% url 'subject_delete' %}?id=" + id,function (data) {
                if(data.status == 0) {
                    swal({
                        title: data.msg,
                        icon: "success",
                        confirmButtonText: '确定',
                    }, function () {
                        window.location.reload()
                    } else {
                    swal("删除失败", {
                        icon: "error",
# 试卷表开始
class Test_Paper_Subject(models.Model):
    stem = models.CharField(max_length=254, verbose_name='题干内容', blank=False, null=False, unique=True)
    type = models.IntegerField(choices=Type, verbose_name='题目类型,单选还是多选')
    explain = models.CharField(max_length=512, verbose_name='题目答案解析', blank=False, null=False)
    test_paper = models.ForeignKey('Test_Paper')
    class Meta:
        db_table = 'test_paper_subject'
        verbose_name = '题干表'
class Test_Paper_options(models.Model):
    options = models.IntegerField(choices=Option, verbose_name='选项ABCDEFGH')
    content = models.CharField(max_length=256, verbose_name='选项内容')
    subject = models.ForeignKey('Test_Paper_Subject')
    class Meta:
        db_table = 'test_paper_options'
        verbose_name = '选项表'
        unique_together = ('subject', 'content')
        ordering = ['options']
class Test_Paper_Answer(models.Model):
    options = models.IntegerField(choices=Option, verbose_name='选项ABCDEFGH')
    subject = models.ForeignKey('Test_Paper_Subject')
    class Meta:
        db_table = 'test_paper_answer'
        verbose_name = '答案表'
        unique_together = ('subject', 'options')
        ordering = ['options']
class Test_Paper(models.Model):
    class Meta:
        db_table = 'test_paper'
# 试卷表结束

  更新数据库

python manage.py makemigrations subject
python manage.py migrate subject
class TestPaperAdd(View):
    def get(self, request):
        subject_obj = Subject.objects.filter(type=0).order_by('?')[:70]
        subject_obj2 = Subject.objects.filter(type=1).order_by('?')[:30]
        # subject_obj = Subject.objects.all()
        Test_Paper.objects.all().delete()
        test_paper = Test_Paper()
        test_paper.save()
        test_paper_id = test_paper.id
        print(test_paper_id)
        for one in subject_obj:
            test_paper_subject = Test_Paper_Subject()
            test_paper_subject.stem = one.stem
            test_paper_subject.type = one.type
            test_paper_subject.explain = one.explain
            test_paper_subject.test_paper_id = test_paper_id
            test_paper_subject.save()
            for options in one.options_set.all():
                test_paper_options = Test_Paper_options()
                print(options.options)
                test_paper_options.options = options.options
                print(options.content)
                test_paper_options.content = options.content
                print(test_paper_subject.id)
                test_paper_options.subject_id = test_paper_subject.id
                test_paper_options.save()
            for answer in one.answer_set.all():
                test_paper_answer = Test_Paper_Answer()
                print(answer.options)
                test_paper_answer.options = answer.options
                test_paper_answer.subject_id = test_paper_subject.id
                test_paper_answer.save()
        for one in subject_obj2:
            test_paper_subject = Test_Paper_Subject()
            test_paper_subject.stem = one.stem
            test_paper_subject.type = one.type
            test_paper_subject.explain = one.explain
            test_paper_subject.test_paper_id = test_paper_id
            test_paper_subject.save()
            for options in one.options_set.all():
                test_paper_options = Test_Paper_options()
                print(options.options)
                test_paper_options.options = options.options
                print(options.content)
                test_paper_options.content = options.content
                print(test_paper_subject.id)
                test_paper_options.subject_id = test_paper_subject.id
                test_paper_options.save()
            for answer in one.answer_set.all():
                test_paper_answer = Test_Paper_Answer()
                print(answer.options)
                test_paper_answer.options = answer.options
                test_paper_answer.subject_id = test_paper_subject.id
                test_paper_answer.save()
        return HttpResponse('随机生成一套试卷')

   页面生成一套试卷

def get(self, request): data = Test_Paper.objects.all() # print(data, data.test_paper_subject_set.all()) for one in data: data2 = one.test_paper_subject_set.all() return render(request, 'test_paper_show.html', {'object_list': data2}) <form id="{{ one.id }}"> {% csrf_token %} {% for options in one.test_paper_options_set.all %} {% if one.type == 0 %} <input type="radio" name={{ one.id }} value="{{ options.options }}"> {{ options.get_options_display }} , {{ options.content }} {% else %} <input type="checkbox" name={{ one.id }} value="{{ options.options }}"> {{ options.get_options_display }} , {{ options.content }} {% endif %} {% endfor %} {# <button class="btn btn-primary" type="submit">确定</button>#} <form/> {# 显示答案#} <p id="{{ one.id }}id" hidden> {% for answer in one.test_paper_answer_set.all %} {{ answer.get_options_display }} {% endfor %} <input type = 'button' onclick=showp("{{ one.id }}id") value='答案'/> {# 显示解析#} <p id="{{ one.id }}explain" hidden >{{ one.explain }} </p> <input type = 'button' onclick=showp("{{ one.id }}explain") value='解析'> <a type = 'button' href="{% url 'subject_update' %}?id={{ one.id }}">修改</a> {# <a type = 'button' onclick="subject_delete({{ one.id }})">删除</a>#} {% endfor %} <script src="/static/js/jquery-3.1.1.min.js"></script> <script src="/static/js/bootstrap.min.js"></script> <script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script> <script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script> <script src="/static/js/plugins/validate/jquery.validate.js"></script> <script src="/static/js/plugins/validate/messages_zh.js"></script> <script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script> <!-- Custom and plugin javascript --> <script src="/static/js/inspinia.js"></script> <script src="/static/js/plugins/pace/pace.min.js"></script> <script type="text/javascript"> function showp(id){ if (document.getElementById(id).style.display == 'inline') { document.getElementById(id).style.display = 'none'; else { document.getElementById(id).style.display='inline'; function subject_delete(id) { if (confirm('确认删除吗?')) { {#alert(id)#} $.get("{% url 'subject_delete' %}?id=" + id,function (data) { if(data.status == 0) { swal({ title: data.msg, icon: "success", confirmButtonText: '确定', }, function () { window.location.reload() } else { swal("删除失败", { icon: "error", </script> </body> </html>

  web页面查看