[项目实训]项目Django后端

       record_with_prompt.py已经完成,能够在命令行界面输入病人描述,然后生成病历(json键值对形式),但是作为一个项目,还需要搭建前端和后端。我们后端选用的是Django,前端使用Vue,完成一个前后端分离的web应用,完成更多复杂的功能,并且将生成的病历信息存入数据库,给患者提供生成病历、查询病历的数据库操作,并且医生能够查看挂号患者的病历,填写诊断结果。

后端项目结构如下:

在urls.py配置相应路由,作为接口暴露给前端。

//case_history.urls.py中的路由配置
urlpatterns = [
    path('admin/', admin.site.urls),
    path('medic/', include('medic_app.urls')),
]

//medic_app.urls.py中的路由配置
urlpatterns = [
    # 登录
    path('login/', views.login, name='login'),
    # 注册
    path('register/', views.register, name='register'),
    # 生成病历
    path('generate/<int:p_id>/', views.generate, name='generate'),
    # 查看病患病历
    path('myCase/<int:p_id>/', views.myCase, name='myCase'),
    # 医生诊断界面
    path('diagnostic/<int:d_id>/', views.diagnostic, name='diagnostic'),
    # 病历界面(通用)
    path('case/<int:p_id>/<int:d_id>/', views.case, name='case'),
]

当后端Django项目启动后,前端往对应路由发送http请求,会发送到view.py中对应路由的函数进行处理,对应函数的return也是返回到对应的前端页面。

在views.py中完成对应逻辑的处理。

其中,对应病历生成的函数generate接收前端传来的message(患者自述),调用本地部署的大模型处理(具体处理方法见上一篇文章:[项目实训]大模型应用:病历自动生成 实现-CSDN博客)

并且利用Django自带的数据库框架,将生成的病历存入数据库中的record表中(这里的inference为调用大模型的方法)

def generate(request, p_id):
    data = request.POST
    print(data)
    message = data['message']
    doctor_id = data['doctor_id']

    custom_settings = init_prompts()

    my_record = inference(message, custom_settings)

    client = MongoClient('mongodb://localhost:27017/')
    db = client['medic_app']
    collection = db['record']


    record = {'p_id': p_id,
              'd_id': doctor_id,
              'name': my_record['姓名'],
              'age' : my_record['年龄'],
              'chief': my_record['主诉'],
              'lastingTime': my_record['持续时间'],
              'history': my_record['既往病史'],
              'allergy': my_record['过敏药物']
              }

    collection.insert_one(record)

    return JsonResponse({"message": my_record}, json_dumps_params={'ensure_ascii': False})

schema = {
    '病历条目': ['姓名', '年龄', '主诉', '持续时间', '既往病史', '过敏药物']
}

IE_PATTERN = "{}\n\n提取上述句子中{}类型的实体,输出JSON格式,如果上述句子没有该信息,则用['无']来表示,多个值之间用','分隔。"

ie_examples = {
    '病历1':
        {
            'sentence': '我叫傅一帆,今年38岁,我从昨天开始感觉头疼,并且伴有腹泻的症状。以前得过肠胃型感冒,对阿莫西林过敏',
            'answers': {
                '姓名': '傅一帆',
                '年龄': '38岁',
                '主诉': '头疼,腹泻',
                '持续时间': '1天',
                '既往病史': '肠胃型感冒',
                '过敏药物': '阿莫西林',
            }
        },
    '病历2':
        {
            'sentence': '我叫林凡,今年42岁,前天开始一直觉得肩膀酸痛,几十年前曾经得过肩周炎,但是已经痊愈,没有发现药物过敏',
            'answers': {
                '姓名': '林凡',
                '年龄': '42岁',
                '主诉': '肩膀酸痛',
                '持续时间': '2天',
                '既往病史': '肩周炎',
                '过敏药物': '未提供',
            }
        },
    '病历3':
        {
            'sentence': '我叫何清,今年13岁,这半个月一直觉得脚疼',
            'answers': {
                '姓名': '何清',
                '年龄': '13岁',
                '主诉': '脚疼',
                '持续时间': '半个月',
                '既往病史': '未提供',
                '过敏药物': '未提供',
            }
        },
    '病历4':
        {
            'sentence': '我叫林露,我觉得牙疼,去年因为口腔癌做过手术',
            'answers': {
                '姓名': '林露',
                '年龄': '未提供',
                '主诉': '牙疼',
                '持续时间': '未提供',
                '既往病史': '口腔癌',
                '过敏药物': '未提供',
            }
        }
}


def init_prompts():
    ie_prefix = [
        (
            "需要你协助完成病历信息抽取任务,当我给你一个病人自述时,帮我抽取出句子中的‘姓名、年龄、主诉、持续时间、既往病史、过敏药物’,并按照\
            JSON的格式输出,如果缺少信息用['未提供']来表示,多个值之间用','分隔。持续时间要说明具体几天或几个月,只要输出json格式数据,不要输出\
            多余信息",
            '好的,我将只以json格式输出。'
        )
    ]
    properties_str = ', '.join(schema['病历条目'])

    schema_str_list = f'“病历条目”({properties_str})'

    for key, example in ie_examples.items():
        sentence = example['sentence']
        formatted_prompt = IE_PATTERN.format(sentence, schema_str_list)
        answers_json = json.dumps(example['answers'], ensure_ascii=False)
        ie_prefix.append((formatted_prompt, answers_json))

    return {'ie_prefix': ie_prefix}


def format_output(response: str):
    if '```json' in response:
        # response = response.replace("\n","")
        res = re.findall(r'```json((.|\n)*?)```', response)
        if len(res) and res[0]:
            response = res[0]
            response = response[0]
        response.replace('、', ',')
    elif '{' in response:
        res = re.findall(r'{((.|\n)*?)}', response)
        if len(res) and res[0]:
            response = res[0]
            response = response[0]
            response = '{' + response + '}'
        response.replace('、', ',')

    try:
        return json.loads(response)
    except:
        return response


def inference(sentence, custom_settings: dict):
    properties_str = ', '.join(schema['病历条目'])
    schema_str_list = f'“病历条目”({properties_str})'
    sentence_with_ie_prompt = IE_PATTERN.format(sentence, schema_str_list)
    result, _ = (model.chat(tokenizer, sentence_with_ie_prompt, history=custom_settings['ie_prefix']))
    result = format_output(result)
    return result

其他还有登录注册、用户病历界面、医生查看病历界面、诊断界面等,这里不一一展示。

使用Postman测试,成功返回需要的json形式的病历数据键值对:

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值