feat: add super-admin stu relationand difficuty
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
},
|
},
|
||||||
"difficulty": {
|
"difficulty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["easy", "medium", "hard", ""]
|
"enum": ["低", "中", "高", ""]
|
||||||
},
|
},
|
||||||
"chief_complaint": { "type": "string" },
|
"chief_complaint": { "type": "string" },
|
||||||
"description": { "type": "string" },
|
"description": { "type": "string" },
|
||||||
|
|||||||
+40
-1
@@ -7,6 +7,7 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
|
from django.db.models import Prefetch
|
||||||
from rest_framework import viewsets, filters, status
|
from rest_framework import viewsets, filters, status
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.parsers import MultiPartParser, FormParser
|
from rest_framework.parsers import MultiPartParser, FormParser
|
||||||
@@ -52,6 +53,12 @@ class CmsUserSerializer(serializers.ModelSerializer):
|
|||||||
"""读取(列表 / 详情)。"""
|
"""读取(列表 / 详情)。"""
|
||||||
institution_name = serializers.CharField(source='institution.name', read_only=True, default=None)
|
institution_name = serializers.CharField(source='institution.name', read_only=True, default=None)
|
||||||
role_label = serializers.SerializerMethodField()
|
role_label = serializers.SerializerMethodField()
|
||||||
|
# 师生关系(仅取进行中 status=1):
|
||||||
|
# - 医生:students = 名下学生 [{id, real_name, phone}],teachers 为 None;
|
||||||
|
# - 学生:teachers = 带教医生 [{id, real_name, phone}],students 为 None;
|
||||||
|
# - 其它角色:两者均为 None。
|
||||||
|
students = serializers.SerializerMethodField()
|
||||||
|
teachers = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
@@ -59,11 +66,33 @@ class CmsUserSerializer(serializers.ModelSerializer):
|
|||||||
'id', 'username', 'real_name', 'phone', 'role_type', 'role_label',
|
'id', 'username', 'real_name', 'phone', 'role_type', 'role_label',
|
||||||
'institution', 'institution_name',
|
'institution', 'institution_name',
|
||||||
'gender', 'title_name', 'major', 'training_stage', 'status', 'created_at',
|
'gender', 'title_name', 'major', 'training_stage', 'status', 'created_at',
|
||||||
|
'students', 'teachers',
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_role_label(self, obj):
|
def get_role_label(self, obj):
|
||||||
return ROLE_LABEL_BY_CODE.get(obj.role_type, obj.role_type)
|
return ROLE_LABEL_BY_CODE.get(obj.role_type, obj.role_type)
|
||||||
|
|
||||||
|
def get_students(self, obj):
|
||||||
|
if obj.role_type != 'doctor':
|
||||||
|
return None
|
||||||
|
# 优先使用 viewset 预取(prefetch)的关系,避免 N+1
|
||||||
|
rels = obj.teacher_relations.all() if 'teacher_relations' in getattr(obj, '_prefetched_objects_cache', {}) \
|
||||||
|
else TeacherStudentRelation.objects.filter(teacher=obj, status=1).select_related('student')
|
||||||
|
return [
|
||||||
|
{'id': r.student_id, 'real_name': r.student.real_name, 'phone': r.student.phone}
|
||||||
|
for r in rels if r.status == 1
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_teachers(self, obj):
|
||||||
|
if obj.role_type != 'student':
|
||||||
|
return None
|
||||||
|
rels = obj.student_relations.all() if 'student_relations' in getattr(obj, '_prefetched_objects_cache', {}) \
|
||||||
|
else TeacherStudentRelation.objects.filter(student=obj, status=1).select_related('teacher')
|
||||||
|
return [
|
||||||
|
{'id': r.teacher_id, 'real_name': r.teacher.real_name, 'phone': r.teacher.phone}
|
||||||
|
for r in rels if r.status == 1
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class CmsUserWriteSerializer(serializers.ModelSerializer):
|
class CmsUserWriteSerializer(serializers.ModelSerializer):
|
||||||
"""新增 / 编辑(role 必填)。"""
|
"""新增 / 编辑(role 必填)。"""
|
||||||
@@ -169,7 +198,17 @@ class CmsUserViewSet(viewsets.ModelViewSet):
|
|||||||
http_method_names = ['get', 'post', 'head', 'options']
|
http_method_names = ['get', 'post', 'head', 'options']
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = User.objects.select_related('institution', 'department').all().order_by('-created_at')
|
# 预取师生关系(仅进行中 status=1)+ 对端用户,列表输出师生关系时避免 N+1
|
||||||
|
qs = (
|
||||||
|
User.objects.select_related('institution', 'department')
|
||||||
|
.prefetch_related(
|
||||||
|
Prefetch('teacher_relations',
|
||||||
|
queryset=TeacherStudentRelation.objects.filter(status=1).select_related('student')),
|
||||||
|
Prefetch('student_relations',
|
||||||
|
queryset=TeacherStudentRelation.objects.filter(status=1).select_related('teacher')),
|
||||||
|
)
|
||||||
|
.all().order_by('-created_at')
|
||||||
|
)
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
if is_super(user):
|
if is_super(user):
|
||||||
return qs
|
return qs
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
{
|
{
|
||||||
"title": "病例标题",
|
"title": "病例标题",
|
||||||
"case_type": "teaching",
|
"case_type": "teaching",
|
||||||
"difficulty": "easy|medium|hard",
|
"difficulty": "低|中|高",
|
||||||
"chief_complaint": "主诉",
|
"chief_complaint": "主诉",
|
||||||
"description": "病例简介/摘要",
|
"description": "病例简介/摘要",
|
||||||
"patient_age": 45,
|
"patient_age": 45,
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
# 规则
|
# 规则
|
||||||
|
|
||||||
1. `case_type` 固定为 `"teaching"`。
|
1. `case_type` 固定为 `"teaching"`。
|
||||||
2. `difficulty` 根据病例复杂度判断:简单常见病 → easy,需鉴别诊断 → medium,多系统/罕见病 → hard。
|
2. `difficulty` 根据病例复杂度判断:简单常见病 → 低,需鉴别诊断 → 中,多系统/罕见病 → 高。
|
||||||
3. `patient_age` 为整数,无法判断填 `null`。
|
3. `patient_age` 为整数,无法判断填 `null`。
|
||||||
4. `patient_gender` 仅 `"male"` 或 `"female"`,无法判断填空字符串。
|
4. `patient_gender` 仅 `"male"` 或 `"female"`,无法判断填空字符串。
|
||||||
5. 标签类字段(symptom_tags、disease_tags 等)至少各提取 1 个,从原文推断。
|
5. 标签类字段(symptom_tags、disease_tags 等)至少各提取 1 个,从原文推断。
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
{
|
{
|
||||||
"title": "病例标题",
|
"title": "病例标题",
|
||||||
"case_type": "traditional",
|
"case_type": "traditional",
|
||||||
"difficulty": "easy|medium|hard",
|
"difficulty": "低|中|高",
|
||||||
"chief_complaint": "主诉",
|
"chief_complaint": "主诉",
|
||||||
"description": "病例简介/摘要",
|
"description": "病例简介/摘要",
|
||||||
"patient_age": 45,
|
"patient_age": 45,
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
# 规则
|
# 规则
|
||||||
|
|
||||||
1. `case_type` 固定为 `"traditional"`。
|
1. `case_type` 固定为 `"traditional"`。
|
||||||
2. `difficulty` 根据病例复杂度判断:简单常见病 → easy,需鉴别诊断 → medium,多系统/罕见病 → hard。
|
2. `difficulty` 根据病例复杂度判断:简单常见病 → 低,需鉴别诊断 → 中,多系统/罕见病 → 高。
|
||||||
3. `patient_age` 为整数,无法判断填 `null`。
|
3. `patient_age` 为整数,无法判断填 `null`。
|
||||||
4. `patient_gender` 仅 `"male"` 或 `"female"`,无法判断填空字符串。
|
4. `patient_gender` 仅 `"male"` 或 `"female"`,无法判断填空字符串。
|
||||||
5. 标签类字段(symptom_tags、disease_tags 等)至少各提取 1 个,从原文推断。
|
5. 标签类字段(symptom_tags、disease_tags 等)至少各提取 1 个,从原文推断。
|
||||||
|
|||||||
Reference in New Issue
Block a user