Open edX LMS Survey Report:为平台收集并上报匿名化聚合数据的调研报告功能

发布时间:2026/9/17 20:25:34

Open edX LMS Survey Report:为平台收集并上报匿名化聚合数据的调研报告功能 Open edX LMS Survey Report为平台收集并上报匿名化聚合数据的调研报告功能【免费下载链接】openedx-platformThe Open edX LMS Studio, powering education sites around the world!项目地址: https://gitcode.com/GitHub_Trending/ed/openedx-platformSurvey Report 是 Open edXopenedx-platform内置于 LMS 中的一个 Django Appopenedx.features.survey_report用于以聚合、匿名的方式收集平台上课程规模化的关键运营指标课程数、活跃学习者、注册量、选课量、证书数并支持将这些指标定期上报给外部 API为年度 Open edX Impact Report 提供数据来源。阅读本文后你将掌握如何理解它上报的五类核心指标口径、如何通过 Django Admin 或命令行generate_report命令生成与发送报告、如何配置SURVEY_REPORT_ENDPOINT等设置项将报告改发到自己指定的端点以及管理后台提醒 Banner 的触发机制。一、功能定位收集哪些聚合、匿名数据Survey Report 的设计目标见 README.rst收集aggregated, anonymized的平台级数据以便跟踪 Open edX 使用量的增长与趋势。它收集的核心指标与数据来源如下指标名称来自 README.rst 与 models.py 中的模型字段注释指标字段含义底层统计口径来自 queries.pycourses_offered平台当前提供的活跃课程总数get_unique_courses_offered()课程已开start 当前时间、未结束end为空或晚于当前时间、且报名数大于MIN_ENROLLS_ACTIVE_COURSE常量值为 5从源码结构看这是用来过滤测试/废弃课程的最小报名量阈值learners近 4 周内有登录的活跃用户数get_recently_active_users(weeks)按last_login 当前时间 - weeks统计调用方固定传入 4 周见下文MAX_WEEKS_SINCE_LAST_LOGINregistered_learners平台历史注册用户总数get_registered_learners()User中is_activeTrue的记录数enrollments平台活跃选课总数get_course_enrollments()is_activeTrue的CourseEnrollment且排除超级用户与 staff 用户generated_certificates已生成证书总数get_generated_certificates()PersistentCourseGrade中passed_timestamp非空的记录数extra_data附加信息如 site_name、openedx-release 版本号直接取设置项SURVEY_REPORT_EXTRA_DATAstate异步生成流程所处状态取值为processing/generated/error三态SURVEY_REPORT_STATES所有查询都通过.using(read_replica_or_default())走只读副本若配置了读副本避免大表统计对主库产生压力见 queries.py。二、数据模型三个核心 Model模型定义在 models.pySurveyReport存储一份报告快照。除上表各指标均为BigIntegerField默认 0外还有created_atauto_nowTrue——报告生成时间Meta.ordering [-created_at]保证列表按时间倒序stateCharFieldmax_length24——异步生成流程状态默认processing完成后置为generated出错置为error。SurveyReportUpload记录发送报告到外部 API这一动作的结果字段包括sent_at发送时间、report外键指向SurveyReport级联删除、status_codeHTTP 状态码、request_details请求响应体max_length255。其中is_uploaded()方法以200 status_code 300判定是否发送成功。SurveyReportAnonymousSiteID当启用匿名上报时持久化一个随机 UUID主键、uuid.uuid4默认值作为站点身份标识。从源码结构看其作用是让同一站点在多次匿名上报中使用同一个 UUID便于接收方做去重与趋势关联。这三个模型对应了 migrations/ 目录下 6 个版本的迁移演进初始模型、state字段、SurveyReportUpload、匿名 UUID 等。三、报告数据是如何生成的api.py调用链核心业务逻辑集中在 api.pyget_report_data()依次调用queries.py的五个统计函数并将settings.SURVEY_REPORT_EXTRA_DATA作为extra_data一并返回。注意活跃学习者的窗口固定为MAX_WEEKS_SINCE_LAST_LOGIN 4周api.py#L23。generate_report()生成流程的状态机入口——若SURVEY_REPORT_ENABLE为False直接抛出异常拒绝生成先落库一条空记录state默认processing调用get_report_data()取数成功后把state更新为generated并紧接着调用send_report_to_external_api()任一步骤异常时把state置为error并向外抛出异常。get_id()决定上报 payload 中的站点身份。ANONYMOUS_SURVEY_REPORT为False默认时返回settings.LMS_BASE即你的 LMS 域名为True时返回SurveyReportAnonymousSiteID中 get-or-create 的 UUID实现匿名但可识别的上报。四、生成并发送报告的两种操作方式方式一Django Admin按 README.rst 的步骤打开你的 LMS 域名/admin/survey_report/surveyreport/进入Survey Report管理页点击Generate Report按钮该按钮来自自定义的 change_list.html 模板勾选想发送的报告使用批量操作admin actionSend report to external API将其发送到外部 API。Admin 端的定制逻辑在 admin.py 中值得注意的几个约束has_add_permission返回False报告不允许手工新建只能由生成流程产生has_delete_permission返回False且移除了delete_selected默认操作报告是历史数据快照不可删除所有字段均设为readonly_fields并隐藏保存按钮changeform_view注入show_saveFalse等上下文管理页对报告只读唯一可执行的动作就是发送report_state列会在报告存在成功上传记录时显示Sent否则显示state本身Processing/Generated/Error。整个 Admin 只在settings.SURVEY_REPORT_ENABLE为真时注册admin.py#L98-L99配合该开关可以完全关闭功能入口。方式二命令行进入 LMS 容器的 Bash shell例如使用tutor dev run lms bash执行./manage.py lms generate_report命令实现位于 management/commands/generate_report.py默认行为是生成 发送先调用generate_report()其内部在取数成功后即会发送一次报告随后若未加--no-send标志命令会再显式调用一次send_report_to_external_api(report_id)如果只想生成、不上报加--no-send参数./manage.py lms generate_report --no-send任意环节失败会抛出CommandError并带上原始错误信息如An error has occurred while survey report was generating. ...参数详情可通过./manage.py lms generate_report --help查看。附Celery 异步任务除了手动触发仓库还提供了 Celery 任务 tasks.pygenerate_survey_report任务名openedx.features.survey_report.tasks.generate_survey_report内部调用generate_report()。从源码结构看这为由外部定时任务如 cron/beat 或 Tutor 插件周期性触发报告生成与上报预留了入口README.rst 中也注明了通过 Tutor 插件可自动化执行该流程相关章节在原文档中标注为 TODO。五、报告如何被发送到外部 API发送逻辑即 api.py 中的send_report_to_external_api(report_id)按report_id取出SurveyReport记录用model_to_dict提取五个指标字段再组装完整 payloadid站点身份LMS_BASE域名或匿名 UUID见get_id()extra_data报告中保存的附加字典created_at格式化为%m-%d-%Y %H:%M:%S的生成时间以 JSON 格式requests.post(settings.SURVEY_REPORT_ENDPOINT, jsondata)发送raise_for_status()对非 2xx 响应抛出异常成功后创建一条SurveyReportUpload记录保存状态码与响应体。也就是说你的SURVEY_REPORT_ENDPOINT端点只需要能接收包含上述字段的 JSON POST 请求即可接收报告。六、配置项全解各设置项在 lms/envs/common.py 中给出默认值.. setting_name注释表明它们是通过paver设置框架暴露给 LMS 的正式配置项设置项类型默认值说明SURVEY_REPORT_ENABLEboolTrue总开关。设为False时Admin 不再注册入口、Banner 消失、generate_report()拒绝生成抛 Survey report generation is not enabledSURVEY_REPORT_ENDPOINTstringhttps://hooks.zapier.com/hooks/catch/11595998/3ouwv7m/报告发送目标 URL需支持 JSON POST。默认为 Open edX 组织的接收端点用于年度 Impact Report 协作可自行覆盖ANONYMOUS_SURVEY_REPORTboolFalseFalse时 payload 中的站点 ID 为LMS_BASE你的 LMS 域名True时改用持久化的随机 UUID 匿名上报SURVEY_REPORT_EXTRA_DATAdict{}附加字典会原样写入报告的extra_data字段并随 payload 上报例如{site_name: ..., openedx-release: ...}SURVEY_REPORT_CHECK_THRESHOLDint6Banner 检查阈值单位月。距最近一次报告超过该月数时提醒见下节前四项的语义描述来自 README.rst 的 Settings for Survey Report 一节默认值取自当前仓库的实际配置。七、Admin Banner 的触发机制为了让 Open edX 运营者不会忘记定期上报该 App 实现了一个管理后台提醒 Banner模板 admin_banner.html配套前端脚本 admin_banner.js。判定逻辑在 context_processors.pyadmin_extra_context(request)作为 context processor 向所有 admin 页面注入show_survey_report_banner上下文仅当SURVEY_REPORT_ENABLE为真且当前请求路径属于 admin 首页reverse(admin:index)前缀匹配时才进行判断should_show_survey_report_banner()取出created_at最新的SurveyReport若其日期早于阈值日期今天 - SURVEY_REPORT_CHECK_THRESHOLD个月由get_months_threshold()基于dateutil.relativedelta计算则显示 Banner若从未生成过任何报告SurveyReport.DoesNotExist同样显示 Banner因此默认行为是距上次生成报告超过 6 个月SURVEY_REPORT_CHECK_THRESHOLD 6时在 admin 首页出现提醒可调整该阈值改变提醒频率。八、小结与相关入口Survey Report 提供了一条统计查询 → 快照落库 → 外部上报 → 结果留痕的完整链路queries.py 负责只读统计api.py 负责生成与发送的状态机admin.py 与 management/commands/generate_report.py 提供两个操作入口context_processors.py 负责周期性提醒。测试方面可参考 tests/test_query_methods.py 与 management/commands/tests/test_generate_report.py其中覆盖了各统计口径与命令的行为验证。若你只想在自己的部署中本地留存报告而不向 Open edX 官方端点上报最简做法是把SURVEY_REPORT_ENDPOINT指向自己的接收端点或配合--no-send仅生成并可通过SURVEY_REPORT_EXTRA_DATA附加站点标识信息。【免费下载链接】openedx-platformThe Open edX LMS Studio, powering education sites around the world!项目地址: https://gitcode.com/GitHub_Trending/ed/openedx-platform创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/17 20:20:33

以身份为边界:Security-101 之 IAM 零信任架构深度解析

以身份为边界:Security-101 之 IAM 零信任架构深度解析 【免费下载链接】Security-101 8 Lessons, Kick-start Your Cybersecurity Learning. 项目地址: https://gitcode.com/GitHub_Trending/se/Security-101 本指南以 Security-101 课程第 2 模块「Identit…

2026/9/17 20:20:33

Feast 与 dbt 集成实战:让 dbt 模型直接成为生产级 AI 特征

Feast 与 dbt 集成实战:让 dbt 模型直接成为生产级 AI 特征 【免费下载链接】feast The Open Source Feature Store for AI/ML 项目地址: https://gitcode.com/GitHub_Trending/fe/feast 在 Feast 开源特征存储(The Open Source Feature Store fo…

2026/9/17 20:20:33

SwiftUI弹窗选型与实现:系统API与自定义方案边界解析

1. 弹窗选型之前,先看清SwiftUI的弹窗家底做SwiftUI开发的人都会遇到一个问题:弹窗到底用系统的还是自己写?这个问题的答案没有大家想得那么非黑即白。系统弹窗的好处是省事、交互统一、天生适配无障碍,但缺点是长什么样由系统说了…

2026/9/17 21:10:37

用Codex在Blender中生成Tiny Glade风格树木的实战指南

看到标题我就笑了。用 Codex 在 Blender 里做 Tiny Glade 风格的树,改了很多轮还是不像——兄弟,你一点都不孤单,我第一个月也这样。当时我盯着屏幕上那棵像腊肠犬尾巴一样扭曲的“树”,一度怀疑 Codex 根本没听说过 Tiny Glade。…

2026/9/17 21:05:37

运动服饰供应链的材料科学驱动范式

简介:本资源是一份聚焦运动服饰品牌战略的深度行业研究报告,面向轻工制造与纺织服装领域的投资者、企业战略管理者及行业研究者,旨在解析Lululemon崛起背后的可复用经营逻辑,并为本土品牌发展与投资决策提供实操参考。报告全文21页…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码