如何在Django的post_save信号中调用接口填充ExamQuestion字段?
解决Django信号中调用外部Go服务填充ExamQuestion字段的问题
你之前用redirect无效的核心原因是:post_save信号不属于HTTP请求响应周期,它是数据库操作完成后触发的后台逻辑,redirect是给视图返回HTTP响应的方法,在信号里调用完全起不了作用。
正确实现思路
在信号中创建ExamQuestion实例后,直接发起HTTP请求调用你的Go服务,拿到返回的question_params、answer_choices、correct_answer数据,再更新对应的ExamQuestion实例。
修改后的代码实现
1. 安装HTTP请求库
首先确保安装requests库用于发起请求:
pip install requests
2. 修正signals.py代码
import requests from django.db.models.signals import post_save from django.dispatch import receiver from .models import ExamApply, ExamQuestion @receiver(post_save, sender=ExamApply) def create_examapply_examquestion(sender, instance, created, **kwargs): if created: question_count = instance.exam.number_of_questions for _ in range(question_count): # 创建空的ExamQuestion实例 question = ExamQuestion.objects.create(exam=instance) # 替换为你的Go服务实际接口地址 go_service_url = "http://your-go-service-address/generate-question" try: # 根据Go服务要求调整请求方法和参数 response = requests.post(go_service_url, json={"some_param": "value"}) response.raise_for_status() # 捕获HTTP状态码错误 question_data = response.json() # 更新目标字段并保存 question.question_params = question_data.get("question_params") question.answer_choices = question_data.get("answer_choices") question.correct_answer = question_data.get("correct_answer") question.save() except requests.exceptions.RequestException as e: # 记录异常日志,避免阻塞主流程 print(f"调用Go服务失败: {str(e)}") # 可选:标记题目生成失败,后续可重试 pass @receiver(post_save, sender=ExamApply) def save_examapply_examquestion(sender, instance, created, **kwargs): instance.exam.save()
关键注意事项
- 替换Go服务地址:把
http://your-go-service-address/generate-question改成你实际的Go服务接口地址,根据Go服务的要求调整请求方法(GET/POST)和携带的参数。 - 异常处理:必须添加异常捕获,避免Go服务不可用时导致整个ExamApply创建失败,建议结合Django日志系统记录错误详情。
- 性能优化:如果题目数量较多,同步请求会阻塞ExamApply的创建流程,可考虑用Celery等异步任务框架,把题目填充逻辑放到后台执行。
- 避免重复执行:确保仅在
created=True时执行逻辑,防止ExamApply更新时重复生成题目。
内容的提问来源于stack exchange,提问作者TheRorange
相关产品推荐
相关产品推荐

