创建正式考试

This commit is contained in:
caoqianming 2021-03-14 22:00:30 +08:00
parent b920e6f701
commit 9554132a66
16 changed files with 572 additions and 12 deletions

View File

@ -0,0 +1,29 @@
import request from '@/utils/request'
export function getexamlist(query) {
return request({
url: '/examtest/exam/',
method: 'get',
params: query
})
}
export function createexam(data) {
return request({
url: '/examtest/exam/',
method: 'post',
data
})
}
export function updateexam(id, data) {
return request({
url: `/examtest/exam/${id}/`,
method: 'put',
data
})
}
export function deleteexam(id) {
return request({
url: `/examtest/exam/${id}/`,
method: 'delete',
})
}

View File

@ -35,10 +35,11 @@ export function deleteTestRule(id) {
}) })
} }
export function getWorkScopeAll() { export function getWorkScopeAll(query) {
return request({ return request({
url: '/examtest/workscope/', url: '/examtest/workscope/',
method: 'get', method: 'get',
params: query
}) })
} }

View File

@ -247,6 +247,21 @@ export const asyncRoutes = [
}, },
] ]
}, },
{
path: '/exammanage',
component: Layout,
redirect: '/exammanage/index',
name: 'Exammanage',
meta: { title: '考试管理', icon: '', perms: []},
children: [
{
path: 'index',
name: 'exam',
component: () => import('@/views/exam/index.vue'),
meta: { title: '考试管理', icon: 'component', perms: ['exam_view'] }
},
]
},
{ {
path: '/analyse', path: '/analyse',
component: Layout, component: Layout,
@ -268,6 +283,7 @@ export const asyncRoutes = [
}, },
] ]
}, },
{ {
path: '/qtest', path: '/qtest',
component: Layout, component: Layout,

View File

@ -64,9 +64,61 @@ div:focus {
padding: 10px; padding: 10px;
} }
.el-table--medium td,   .el-table--medium th {
padding: 2px 0;
}
.el-form-item {
margin-bottom: 16px;
}
.el-card, .el-message {
border-radius: 0px;
overflow: hidden;
}
.el-card__body { .el-card__body {
padding: 6px; padding: 6px;
} }
.el-card__header { .el-card__header {
padding: 6px; padding: 6px;
} }
.el-tabs--border-card>.el-tabs__content {
padding: 6px;
}
.el-dialog__header {
padding: 10px 10px 6px;
}
// .el-dialog{
// display: flex;
// flex-direction: column;
// margin:0 !important;
// position:absolute;
// top:50%;
// left:50%;
// transform:translate(-50%,-50%);
// /*height:600px;*/
// max-height:calc(100% - 30px);
// max-width:calc(100% - 30px);
// }
.el-dialog .el-dialog__body{
// flex:1;
// overflow: auto;
padding: 8px 12px;
}
.el-form--label-top .el-form-item__label {
line-height: 16px;
}
.el-button+.el-button {
margin-left: 1px;
}
.el-tabs__header {
margin: 0 0 6px;
}
.pagination-container {
padding: 0px 0px;
}
body .el-table th.gutter{
display: table-cell!important;
}
.el-dialog__footer{
padding: 6px 6px 6px;
}

View File

@ -0,0 +1,273 @@
<template>
<div class="app-container">
<div style="margin-top:10px">
<el-input
v-model="listQuery.search"
placeholder="输入考试名称进行搜索"
style="width: 300px;"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button type="primary" @click="handleAdd" icon="el-icon-plus" v-if ="checkPermission(['exam_create'])">新增</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>刷新重置</el-button>
</div>
<el-table
:data="tableData.results"
style="width: 100%;margin-top:10px;"
border
fit
v-loading="listLoading"
highlight-current-row
max-height="600"
row-key="id"
default-expand-all
>
<el-table-column label="考试名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="考试编号">
<template slot-scope="scope">{{ scope.row.code }}</template>
</el-table-column>
<el-table-column label="考试地点">
<template slot-scope="scope">{{ scope.row.place }}</template>
</el-table-column>
<el-table-column label="工作类别">
<template slot-scope="scope">{{ scope.row.workscope }}</template>
</el-table-column>
<el-table-column label="开启时间">
<template slot-scope="scope">{{ scope.row.opentime }}</template>
</el-table-column>
<el-table-column label="关闭时间">
<template slot-scope="scope">{{ scope.row.closetime }}</template>
</el-table-column>
<el-table-column label="创建人">
<template slot-scope="scope">
<span>{{ scope.row.create_admin_name }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleView(scope)"
:disabled="!checkPermission(['exam_view'])"
>详情</el-button>
<el-button
size="small"
@click="handleEdit(scope)"
:disabled="!checkPermission(['exam_update'])"
>编辑</el-button>
<el-button
type="danger"
size="small"
@click="handleDelete(scope)"
:disabled="!checkPermission(['exam_delete'])"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="tableData.count>0"
:total="tableData.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'编辑考试':'新增考试'" >
<el-form :model="exam" label-width="80px" :rules="rule1" ref="examForm">
<el-form-item label="名称" prop="name">
<el-input v-model="exam.name" placeholder="名称" />
</el-form-item>
<el-form-item label="考试地点" prop="place">
<el-input v-model="exam.place" placeholder="考试地点" />
</el-form-item>
<el-form-item label="工作类别" prop="workscope" >
<el-select v-model="exam.workscope" placeholder="请选择工作类别" style="width:100%">
<el-option
v-for="item in workscopeOptions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="开启时间" prop="opentime">
<el-date-picker
v-model="exam.opentime"
type="datetime"
placeholder="开启时间"
style="width:100%">
</el-date-picker>
</el-form-item>
<el-form-item label="关闭时间" prop="closetime">
<el-date-picker
v-model="exam.closetime"
type="datetime"
placeholder="关闭时间"
style="width:100%"
></el-date-picker>
</el-form-item>
<el-form-item label="监考人姓名" prop="proctor_name" label-width="120px">
<el-input v-model="exam.proctor_name" placeholder="监考人姓名" />
</el-form-item>
<el-form-item label="监考人联系方式" prop="proctor_phone" label-width="120px">
<el-input v-model="exam.proctor_phone" placeholder="监考人联系方式" />
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="confirmexam('examForm')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getexamlist, createexam, deleteexam, updateexam} from "@/api/exam";
import { getWorkScopeAll } from "@/api/examtest"
import { deepClone } from "@/utils";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"
const defaultexam = {
id: "",
name: "",
place: "",
opentime: null,
closetime: null,
};
const listQuery = {
page: 1,
limit: 20,
search: ""
}
export default {
components: { Pagination },
data() {
return {
selects:[],
exam: {
id: "",
name: "",
},
listQuery:listQuery,
tableData: {count:0},
listLoading: true,
dialogVisible: false,
dialogType: "new",
workscopeOptions:[],
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
place: [{ required: true, message: "请输入", trigger: "change" }],
workscope: [{ required: true, message: "请选择", trigger: "change" }],
opentime: [{ required: true, message: "请选择", trigger: "change" }],
closetime: [{ required: true, message: "请选择", trigger: "change" }],
proctor_name: [{ required: true, message: "请输入", trigger: "change" }],
proctor_phone: [{ required: true, message: "请输入", trigger: "change" }]
},
};
},
computed: {},
created() {
this.getList();
this.getworkscopeOptions();
},
methods: {
checkPermission,
getworkscopeOptions(){
getWorkScopeAll({can_exam:true}).then(res=>{
this.workscopeOptions = res.data
})
},
getList() {
this.listLoading = true
getexamlist(this.listQuery).then(response => {
this.tableData = response.data
this.listLoading = false
});
},
resetFilter() {
this.listQuery = {
page: 1,
limit: 20,
search: ""
};
this.getList();
},
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
handleAdd() {
this.exam = Object.assign({}, defaultexam);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["examForm"].clearValidate();
});
},
handleEdit(scope) {
this.exam = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["examForm"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除该考试吗?将丢失数据!", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error"
})
.then(async () => {
await deleteexam(scope.row.id);
this.getList()
this.$message({
type: "success",
message: "成功删除!"
});
})
.catch(err => {
// console.error(err);
});
},
handleView(scope){
},
async confirmexam(form) {
this.$refs[form].validate(valid => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateexam(this.exam.id, this.exam).then(() => {
this.getList();
this.dialogVisible = false;
this.$message.success('成功')
});
} else {
createexam(this.exam).then(res => {
// this.exam = res.data
// this.tableData.unshift(this.exam)
this.getList();
this.dialogVisible = false;
this.$message.success('成功')
});
}
} else {
return false;
}
});
},
}
};
</script>

View File

@ -20,14 +20,20 @@
row-key="id" row-key="id"
> >
<el-table-column type="index" width="50"></el-table-column> <el-table-column type="index" width="50"></el-table-column>
<el-table-column align="center" label="名称"> <el-table-column label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template> <template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="所属学科"> <el-table-column label="所属学科">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag type="success" >{{scope.row.subject_name}}</el-tag> <el-tag type="success" >{{scope.row.subject_name}}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="是否可组织考试">
<template slot-scope="scope">
<el-tag v-if="scope.row.can_exam"></el-tag>
<el-tag type="warning" v-else></el-tag>
</template>
</el-table-column>
<el-table-column label="创建日期"> <el-table-column label="创建日期">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ scope.row.create_time }}</span> <span>{{ scope.row.create_time }}</span>

View File

@ -10,6 +10,9 @@
<el-form-item label="工作类别" prop="name"> <el-form-item label="工作类别" prop="name">
<el-input v-model="Form.name" style="width:400px"></el-input> <el-input v-model="Form.name" style="width:400px"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="是否可组织考试" prop="can_exam" label-width="120px">
<el-switch v-model="Form.can_exam"></el-switch>
</el-form-item>
<el-form-item label="所属学科" prop="subject"> <el-form-item label="所属学科" prop="subject">
<el-select v-model="Form.subject" placeholder="请选择所属学科" style="width:400px"> <el-select v-model="Form.subject" placeholder="请选择所属学科" style="width:400px">
<el-option <el-option
@ -57,6 +60,7 @@ export default {
return { return {
Form: { Form: {
name: "", name: "",
can_exam:false,
subject: null, subject: null,
questioncat: [], questioncat: [],
}, },

View File

@ -10,6 +10,9 @@
<el-form-item label="工作类别" prop="name"> <el-form-item label="工作类别" prop="name">
<el-input v-model="Form.name" style="width:400px"></el-input> <el-input v-model="Form.name" style="width:400px"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="是否可组织考试" prop="can_exam" label-width="120px">
<el-switch v-model="Form.can_exam"></el-switch>
</el-form-item>
<el-form-item label="所属学科" prop="subject"> <el-form-item label="所属学科" prop="subject">
<el-select v-model="Form.subject" placeholder="请选择所属学科" style="width:400px"> <el-select v-model="Form.subject" placeholder="请选择所属学科" style="width:400px">
<el-option <el-option
@ -57,6 +60,7 @@ export default {
return { return {
Form: { Form: {
name: "", name: "",
can_exam:false,
subject: null, subject: null,
questioncat: [], questioncat: [],
}, },

View File

@ -0,0 +1,53 @@
# Generated by Django 3.0.4 on 2021-03-14 09:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('examtest', '0024_auto_20200402_2353'),
]
operations = [
migrations.AddField(
model_name='workscope',
name='can_exam',
field=models.BooleanField(default=False, verbose_name='是否可组织考试'),
),
migrations.AlterField(
model_name='examtest',
name='type',
field=models.CharField(choices=[('自助模考', '自助模考'), ('押卷模考', '押卷模考'), ('正式考试', '正式考试')], default='自助模考', max_length=50, verbose_name='考试类型'),
),
migrations.CreateModel(
name='Exam',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_delete', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('code', models.CharField(blank=True, max_length=100, null=True, verbose_name='考试编号')),
('name', models.CharField(max_length=100, verbose_name='名称')),
('place', models.CharField(blank=True, max_length=100, null=True, verbose_name='考试地点')),
('opentime', models.DateTimeField(blank=True, null=True, verbose_name='开启时间')),
('closetime', models.DateTimeField(blank=True, null=True, verbose_name='关闭时间')),
('proctor_name', models.CharField(max_length=100, verbose_name='监考人姓名')),
('proctor_phone', models.CharField(max_length=100, verbose_name='监考人联系方式')),
('create_admin', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='exam_create_admin', to=settings.AUTH_USER_MODEL)),
('workscope', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='examtest.WorkScope', verbose_name='工作类别')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='examtest',
name='exam',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='examtest_exam', to='examtest.Exam', verbose_name='关联的正式考试'),
),
]

View File

@ -1,5 +1,5 @@
from django.db import models from django.db import models
from rbac.models import SoftCommonModel, CommonModel from rbac.models import SoftCommonModel, CommonModel, UserProfile
from django.contrib.postgres.fields import JSONField, ArrayField from django.contrib.postgres.fields import JSONField, ArrayField
from question.models import Questioncat, Question from question.models import Questioncat, Question
from crm.models import Consumer from crm.models import Consumer
@ -7,7 +7,20 @@ from .models_paper import WorkScope, Paper
class Exam(CommonModel): class Exam(CommonModel):
pass """
组织的正式考试
"""
code = models.CharField('考试编号', max_length=100, null=True, blank=True)
name = models.CharField('名称', max_length=100)
place = models.CharField('考试地点', max_length=100, null=True, blank=True)
workscope = models.ForeignKey(WorkScope, verbose_name='工作类别', on_delete= models.DO_NOTHING)
opentime = models.DateTimeField('开启时间', null=True, blank=True)
closetime = models.DateTimeField('关闭时间', null=True, blank=True)
proctor_name = models.CharField('监考人姓名', max_length=100)
proctor_phone = models.CharField('监考人联系方式', max_length=100)
create_admin = models.ForeignKey(UserProfile, on_delete=models.SET_NULL, null=True, blank=True, related_name='exam_create_admin')
class ExamTest(CommonModel): class ExamTest(CommonModel):
@ -17,6 +30,7 @@ class ExamTest(CommonModel):
type_choices = ( type_choices = (
('自助模考', '自助模考'), ('自助模考', '自助模考'),
('押卷模考', '押卷模考'), ('押卷模考', '押卷模考'),
('正式考试', '正式考试')
) )
name = models.CharField(max_length=200, verbose_name='名称') name = models.CharField(max_length=200, verbose_name='名称')
type = models.CharField(max_length=50, default='自助模考',choices = type_choices, verbose_name='考试类型') type = models.CharField(max_length=50, default='自助模考',choices = type_choices, verbose_name='考试类型')
@ -31,6 +45,8 @@ class ExamTest(CommonModel):
end_time = models.DateTimeField(verbose_name='结束答题时间') end_time = models.DateTimeField(verbose_name='结束答题时间')
detail = models.ManyToManyField(Question, related_name='答题记录', through='AnswerDetail') detail = models.ManyToManyField(Question, related_name='答题记录', through='AnswerDetail')
is_pass = models.BooleanField(default=True, verbose_name='是否通过') is_pass = models.BooleanField(default=True, verbose_name='是否通过')
exam = models.ForeignKey(Exam, verbose_name='关联的正式考试', null=True, blank=True, related_name='examtest_exam', on_delete= models.SET_NULL)
class Meta: class Meta:
verbose_name = '模拟考试' verbose_name = '模拟考试'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from django.template.defaultfilters import default
from rbac.models import SoftCommonModel, CommonModel from rbac.models import SoftCommonModel, CommonModel
from django.contrib.postgres.fields import JSONField, ArrayField from django.contrib.postgres.fields import JSONField, ArrayField
from question.models import Questioncat, Question from question.models import Questioncat, Question
@ -31,6 +32,7 @@ class WorkScope(CommonModel):
subject = models.ForeignKey(Questioncat, verbose_name='所属学科', on_delete=models.CASCADE , related_name='workscope_subject') subject = models.ForeignKey(Questioncat, verbose_name='所属学科', on_delete=models.CASCADE , related_name='workscope_subject')
questioncat = models.ManyToManyField(Questioncat, verbose_name='所选科目') questioncat = models.ManyToManyField(Questioncat, verbose_name='所选科目')
rule = models.ForeignKey(TestRule, on_delete=models.CASCADE, verbose_name='试卷结构') rule = models.ForeignKey(TestRule, on_delete=models.CASCADE, verbose_name='试卷结构')
can_exam = models.BooleanField('是否可组织考试', default=False)
class Meta: class Meta:
verbose_name = '工作类别' verbose_name = '工作类别'

View File

@ -1,7 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from question.models import Questioncat from question.models import Questioncat
from crm.models import Consumer from crm.models import Consumer
from .models import ExamTest, AnswerDetail, Banner from .models import Exam, ExamTest, AnswerDetail, Banner
from .models_paper import TestRule, WorkScope, Paper, PaperQuestions from .models_paper import TestRule, WorkScope, Paper, PaperQuestions
from question.serializers import QuestionSerializer from question.serializers import QuestionSerializer
@ -163,3 +163,14 @@ class PaperQuestionsCreateSerializer(serializers.ModelSerializer):
model = PaperQuestions model = PaperQuestions
fields = '__all__' fields = '__all__'
class ExamCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = Exam
fields = ['name', 'place', 'opentime', 'closetime', 'proctor_name', 'proctor_phone', 'workscope']
class ExamListSerializer(serializers.ModelSerializer):
create_admin_username = serializers.StringRelatedField(source='create_admin')
workscope_name = serializers.StringRelatedField(source='workscope')
class Meta:
model = Exam
fields = '__all__'

View File

@ -1,5 +1,5 @@
from django.urls import path,include from django.urls import path,include
from .views import TestRuleViewSet, AnswerDetailView, WorkScopeViewSet, BannerViewSet, ExamTestViewSet, PaperViewSet from .views import TestRuleViewSet, AnswerDetailView, WorkScopeViewSet, BannerViewSet, ExamTestViewSet, PaperViewSet, ExamViewSet
from rest_framework import routers from rest_framework import routers
@ -9,6 +9,7 @@ router.register('workscope', WorkScopeViewSet, basename="workscope")
router.register('banner', BannerViewSet, basename='banner') router.register('banner', BannerViewSet, basename='banner')
router.register('examtest', ExamTestViewSet, basename='examtest') router.register('examtest', ExamTestViewSet, basename='examtest')
router.register('paper', PaperViewSet, basename='paper') router.register('paper', PaperViewSet, basename='paper')
router.register('exam', ExamViewSet, basename='exam')
urlpatterns = [ urlpatterns = [
path('answerdetail/', AnswerDetailView.as_view()), path('answerdetail/', AnswerDetailView.as_view()),

View File

@ -18,18 +18,59 @@ from question.models import Question
from question.serializers import QuestionSerializer from question.serializers import QuestionSerializer
from server import settings from server import settings
from utils.custom import CommonPagination from utils.custom import CommonPagination
from utils.mixins import OptimizationMixin
from .exports import export_test from .exports import export_test
from .models import AnswerDetail, Banner, ExamTest from .models import AnswerDetail, Banner, ExamTest, Exam
from .models_paper import Paper, PaperQuestions, TestRule, WorkScope from .models_paper import Paper, PaperQuestions, TestRule, WorkScope
from .serializers import ( from .serializers import (
AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer, AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer,
ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer, ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer,
PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer, PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer,
WorkScopeSerializer) WorkScopeSerializer, ExamCreateUpdateSerializer, ExamListSerializer)
# Create your views here. # Create your views here.
class ExamViewSet(ModelViewSet):
"""
正式考试增删改查
"""
perms_map = [
{'get': 'exam_view'}, {'post': 'exam_create'},
{'put': 'exam_update'}, {'delete': 'exam_delete'}]
pagination_class = CommonPagination
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
ordering = ['-id']
search_fields = ['name']
def get_queryset(self):
queryset = Exam.objects.all()
if not self.request.user.is_superuser:
queryset = queryset.filter(create_admin = self.request.user)
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset) # 性能优化
return queryset
def get_serializer_class(self):
if self.action in ['create', 'update']:
return ExamCreateUpdateSerializer
return ExamListSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = serializer.save(create_admin=request.user)
instance.code = instance.pk + 10000
instance.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
if ExamTest.objects.filter(exam=instance).exists():
return Response({'error':'存在考试记录,禁止删除'})
instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class AnswerDetailView(APIView): class AnswerDetailView(APIView):
authentication_classes = [] authentication_classes = []
@ -56,8 +97,8 @@ class WorkScopeViewSet(ModelViewSet):
ordering_fields = ('id',) ordering_fields = ('id',)
ordering = ['id'] ordering = ['id']
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['subject'] filterset_fields = ['subject', 'can_exam']
search_fields = ('^name',) search_fields = ('name',)
def get_queryset(self): def get_queryset(self):
queryset = self.queryset queryset = self.queryset
@ -102,6 +143,7 @@ class WorkScopeViewSet(ModelViewSet):
b3_set = queryset.filter(questioncat=questioncats[2], type='多选').order_by('?')[:b3] b3_set = queryset.filter(questioncat=questioncats[2], type='多选').order_by('?')[:b3]
question_queryset = question_queryset|a1_set|a2_set|a3_set|b1_set|b2_set|b3_set question_queryset = question_queryset|a1_set|a2_set|a3_set|b1_set|b2_set|b3_set
elif workscope.name == '辐射安全管理': elif workscope.name == '辐射安全管理':
# 辐射安全管理出卷规则
queryset = Question.objects.filter(is_delete=0) queryset = Question.objects.filter(is_delete=0)
a1_set = queryset.filter(questioncat=questioncats[0], type='单选').order_by('?')[:16] a1_set = queryset.filter(questioncat=questioncats[0], type='单选').order_by('?')[:16]
a2_set = queryset.filter(questioncat=questioncats[1], type='单选').order_by('?')[:24] a2_set = queryset.filter(questioncat=questioncats[1], type='单选').order_by('?')[:24]
@ -109,6 +151,7 @@ class WorkScopeViewSet(ModelViewSet):
b2_set = queryset.filter(questioncat=questioncats[1], type='多选').order_by('?')[:6] b2_set = queryset.filter(questioncat=questioncats[1], type='多选').order_by('?')[:6]
question_queryset = question_queryset|a1_set|a2_set|b1_set|b2_set question_queryset = question_queryset|a1_set|a2_set|b1_set|b2_set
elif workscope.name == '科研、生产及其他': elif workscope.name == '科研、生产及其他':
# 科研、生产及其他出卷规则
queryset = Question.objects.filter(is_delete=0) queryset = Question.objects.filter(is_delete=0)
a1_set = queryset.filter(questioncat=questioncats[0], type='单选').order_by('?')[:24] a1_set = queryset.filter(questioncat=questioncats[0], type='单选').order_by('?')[:24]
a2_set = queryset.filter(questioncat=questioncats[1], type='单选').order_by('?')[:16] a2_set = queryset.filter(questioncat=questioncats[1], type='单选').order_by('?')[:16]

View File

@ -0,0 +1,48 @@
from django.db.models.query import QuerySet
class CreateUpdateModelAMixin:
"""
业务用基本表A用
"""
def perform_create(self, serializer):
serializer.save(create_by = self.request.user)
def perform_update(self, serializer):
serializer.save(update_by = self.request.user)
class CreateUpdateModelBMixin:
"""
业务用基本表B用
"""
def perform_create(self, serializer):
serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
def perform_update(self, serializer):
serializer.save(update_by = self.request.user)
class CreateUpdateCustomMixin:
"""
整合
"""
def perform_create(self, serializer):
if hasattr(self.queryset.model, 'belong_dept'):
serializer.save(create_by = self.request.user, belong_dept=self.request.user.dept)
else:
serializer.save(create_by = self.request.user)
def perform_update(self, serializer):
serializer.save(update_by = self.request.user)
class OptimizationMixin:
"""
性能优化,需要在序列化器里定义setup_eager_loading,可在必要的View下继承
"""
def get_queryset(self):
queryset = self.queryset
if isinstance(queryset, QuerySet):
# Ensure queryset is re-evaluated on each request.
queryset = queryset.all()
if hasattr(self.get_serializer_class(), 'setup_eager_loading'):
queryset = self.get_serializer_class().setup_eager_loading(queryset) # 性能优化
return queryset

1
test_server/x.py Normal file
View File

@ -0,0 +1 @@
from sympy import *