活动类型附件

这是关于 Google 课堂插件的第五个演示 演示系列视频

在本演示中,您将修改上一个演示步骤中的示例 以生成 activity 类型的附件。这些是任何 要求学生提交内容,例如书面回复、测验或其他 学生生成的工件。

区分内容类型和活动类型附件非常重要。 活动类型附件与内容类型附件的不同之处如下:

  • “上交”按钮显示在“学生视图 iframe”的右上角。
  • 并为学生的作业提供唯一标识符。
  • 他们的附件卡片会显示在 Google 课堂评分者界面中。
  • 他们可以为所属的作业设置成绩。

请参阅下一篇演示,了解有关评分的讨论。在此过程中 您需完成以下操作:

  • 将之前的附件创建请求修改为 Classroom API 创建活动类型的附件。
  • 为学生提交的作业实现永久性存储。
  • 修改之前的“学生视图”路由以接受学生输入的内容。
  • 提供传送学生作业评价 iframe 的路径。

完成后,您可以通过 Google 课堂界面(以教师身份登录时)。课程中的学生可以 在 iframe 中完成活动并提交响应。教师可以 在 Google 课堂评分界面中查看学生提交的作业。

在本示例中,请重复使用 显示著名地标的图片并附有说明文字的演示 替换为地标的名称。活动包括提示学生 用于提供地标的名称。

修改附件创建请求

导航到您在其中创建了 content-type 的代码部分 请参阅前面演示中的“附件”部分。这里的关键项目是 AddOnAttachment 对象,其中我们之前指定了 teacherViewUristudentViewUri,对于连接,则为 title

虽然所有插件附件都需要这三个字段,但在线状态或 studentWorkReviewUri 的缺失将决定连接是否 activity-type 或 content-type。一个 CREATE 请求,其中包含一个填充的 studentWorkReviewUri 变为 activity 类型的附件,而 CREATEstudentWorkReviewUri 请求将成为内容类型附件。

对该请求唯一要做的修改是填充 studentWorkReviewUri 字段。在此处添加适当命名的路线;您 实现它

Python

在我们提供的示例中,它位于create_attachments webapp/attachment_routes.py 文件。

attachment = {
    # Specifies the route for a teacher user.
    "teacherViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True),
    },
    # Specifies the route for a student user.
    "studentViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True)
    },
    # Specifies the route for a teacher user when the attachment is
    # loaded in the Classroom grading view.
    # The presence of this field marks this as an activity-type attachment.
    "studentWorkReviewUri": {
        "uri":
            flask.url_for(
                "view_submission", _scheme='https', _external=True)
    },
    # The title of the attachment.
    "title": f"Attachment {attachment_count}",
}

为内容类型附件添加永久性存储空间

记录学生对我们活动的回答。您可以稍后在 教师在“学生的作业回顾”iframe 中查看提交内容。

Submission 设置数据库架构。我们提供的示例要求 输入图片中显示的地标名称。Submission 因此包含以下属性:

  • attachment_id:连接的唯一标识符。分配者 创建 Google 课堂时在响应中返回了 附件。
  • submission_id:学生提交的标识符。分配者 “课堂”,并在以下视频的getAddOnContext”回复中发回 学生视图
  • student_response:学生提供的答案。

Python

扩展前面步骤中的 SQLite 和 flask_sqlalchemy 实现。

导航到您之前在其中定义了上述表的文件 (如果您遵循我们提供的示例,则为 models.py)。在以下位置添加以下内容: 文件底部

# Database model to represent a student submission.
class Submission(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    submission_id = db.Column(db.String(120), primary_key=True)

    # The unique identifier for the student's submission.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The student's response to the question prompt.
    student_response = db.Column(db.String(120))

将新的 Submission 类连同附件一起导入到服务器文件中 处理路线。

修改“学生视图”路由

接下来,修改之前的“学生视图”路线,以显示小表单并接受 输入的内容。您可以重复使用上一课中的大部分代码 演示。

找到提供学生视图路线的服务器代码。这是 创建连接时在 studentViewUri 字段中指定的路由。 要做的第一项更改是将 submissionIdgetAddOnContext 响应

Python

在我们提供的示例中,它位于 load_activity_attachment 方法中的 webapp/attachment_routes.py 文件。

# Issue a request to the courseWork.getAddOnContext endpoint
addon_context_response = classroom_service.courses().courseWork(
).getAddOnContext(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"]).execute()

# One of studentContext or teacherContext will be populated.
user_context = "student" if addon_context_response.get(
    "studentContext") else "teacher"

# If the user is a student...
if user_context == "student":
    # Extract the submissionId from the studentContext object.
    # This value is provided by Google Classroom.
    flask.session["submissionId"] = addon_context_response.get(
            "studentContext").get("submissionId")

您也可以请求获取学生提交状态。 响应包含一个 SubmissionState 值,该值指明了 例如学生是打开附件还是上交附件。这可能是 如果您想禁止上交的提交内容进行修改, 希望教师能够深入了解学生的进度:

Python

在我们提供的示例中,这是 load_activity_attachment 方法。

# Issue a request to get the status of the student submission.
submission_response = classroom_service.courses().courseWork(
).addOnAttachments().studentSubmissions().get(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    attachmentId=flask.session["attachmentId"],
    submissionId=flask.session["submissionId"]).execute()

最后,从我们的数据库获取附件信息, 表单。我们所提供示例中的表单由一个字符串输入字段和一个 提交按钮。显示地标图片,并提示学生输入名称。 他们给出回复后,请将其记录在我们的数据库中。

Python

在我们提供的示例中,这是 load_activity_attachment 方法。

# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])

message_str = f"I see that you're a {user_context}! "
message_str += (
    f"I've loaded the attachment with ID {attachment.attachment_id}. "
    if user_context == "teacher" else
    "Please complete the activity below.")

form = activity_form_builder()

if form.validate_on_submit():
    # Record the student's response in our database.

    # Check if the student has already submitted a response.
    # If so, update the response stored in the database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    if student_submission is not None:
        student_submission.student_response = form.student_response.data
    else:
        # Store the student's response by the submission ID.
        new_submission = Submission(
            submission_id=flask.session["submissionId"],
            attachment_id=flask.session["attachmentId"],
            student_response=form.student_response.data)
        db.session.add(new_submission)

    db.session.commit()

    return flask.render_template(
        "acknowledge-submission.html",
        message="Your response has been recorded. You can close the " \
            "iframe now.",
        instructions="Please Turn In your assignment if you have " \
            "completed all tasks."
    )

# Show the activity.
return flask.render_template(
    "show-activity-attachment.html",
    message=message_str,
    image_filename=attachment.image_filename,
    image_caption=attachment.image_caption,
    user_context=user_context,
    form=form,
    responses=response_strings)

为了区分用户,不妨考虑禁止提交 函数,改为在教师视图中显示正确答案。

为学生作业回顾 iframe 添加路线

最后,添加用于传送学生作业评价 iframe 的路径。此元素的名称 应与创建 studentWorkReviewUri 时提供的路线一致 附件。教师查看学生提交的作业时,系统会打开此路线 Google 课堂评分者界面。

选择 Google 课堂时,您会收到 submissionId 查询参数 打开学生作业回顾 iframe。使用它检索学生的作业 您的本地数据库:

Python

在我们提供的示例中,它位于 webapp/attachment_routes.py 文件中。

@app.route("/view-submission")
def view_submission():
    """
    Render a student submission using the show-student-submission.html template.
    """

    # Save the query parameters passed to the iframe in the session, just as we did
    # in previous routes. Abbreviated here for readability.
    add_iframe_query_parameters_to_session(flask.request.args)

    # For the sake of brevity in this example, we'll skip the conditional logic
    # to see if we need to authorize the user as we have done in previous steps.
    # We can assume that the user that reaches this route is a teacher that has
    # already authorized and created an attachment using the add-on.

    # In production, we recommend fully validating the user's authorization at
    # this stage as well.

    # Look up the student's submission in our database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    # Look up the attachment in the database.
    attachment = Attachment.query.get(student_submission.attachment_id)

    # Render the student's response alongside the correct answer.
    return flask.render_template(
        "show-student-submission.html",
        message=f"Loaded submission {student_submission.submission_id} for "\
            f"attachment {attachment.attachment_id}.",
        student_response=student_submission.student_response,
        correct_answer=attachment.image_caption)

测试插件

重复测试上一演示中的插件步骤。您应该 包含学生可以打开的附件。

如需测试 activity 连接,请完成以下步骤:

  • 登录 Google 课堂。 作为您的 与教师测试用户位于同一课程中的 student 测试用户。
  • 导航至课业标签页,然后展开测试作业
  • 点击插件附件卡片以打开“学生视图”,然后提交 响应。
  • 完成活动后关闭 iframe。(可选)点击 启用按钮。

完成后,您在 Google 课堂中应该不会发现任何变化 相应活动现在,测试学生作业回顾 iframe:

  • 教师测试用户的身份登录“课堂”。
  • 成绩标签页中找到测试作业对应的列。点击 测试作业的名称。
  • 找到测试学生用户的卡片。点击卡片上的附件。

确认系统显示该学生提交的正确作业。

恭喜!您已准备好继续执行下一步:同步附件 成绩