Đây là hướng dẫn thứ năm trong loạt hướng dẫn về tiện ích bổ sung Lớp học.
Trong hướng dẫn này, bạn sẽ sửa đổi ví dụ ở bước hướng dẫn trước để tạo ra một tệp đính kèm thuộc loại hoạt động. Đây là mọi tệp đính kèm yêu cầu học viên phải nộp bài, chẳng hạn như câu trả lời bằng văn bản, bài kiểm tra hoặc các sản phẩm khác do học viên tạo.
Điều quan trọng là bạn phải phân biệt được tệp đính kèm thuộc loại nội dung và tệp đính kèm thuộc loại hoạt động. Tệp đính kèm theo loại hoạt động khác với tệp đính kèm theo loại nội dung ở những điểm sau:
- Nút "Nộp bài" sẽ xuất hiện ở trên cùng bên phải của iframe Chế độ xem của học viên.
- Chúng cung cấp giá trị nhận dạng riêng biệt cho bài tập của học viên.
- Thẻ tệp đính kèm của họ sẽ xuất hiện trong giao diện người dùng của công cụ chấm điểm trong Lớp học.
- Họ có thể đặt điểm cho bài tập mà họ thuộc về.
Hãy xem hướng dẫn tiếp theo để biết thông tin thảo luận về cách chấm điểm. Trong quá trình thực hiện hướng dẫn này, bạn sẽ hoàn tất những việc sau:
- Sửa đổi các yêu cầu tạo tệp đính kèm trước đó thành Classroom API để tạo một tệp đính kèm thuộc loại hoạt động.
- Triển khai bộ nhớ liên tục cho bài tập mà học viên đã gửi.
- Sửa đổi tuyến đường Chế độ xem học viên trước đó để chấp nhận thông tin đầu vào của học viên.
- Cung cấp một tuyến đường để phân phát iframe Đánh giá bài tập của học viên.
Sau khi hoàn tất, bạn có thể tạo tệp đính kèm thuộc loại hoạt động cho bài tập thông qua giao diện người dùng Google Lớp học khi đăng nhập với tư cách là giáo viên. Học viên trong lớp cũng có thể hoàn thành hoạt động này trong iframe và gửi câu trả lời. Giáo viên có thể xem bài tập đã nộp của học viên trong giao diện chấm điểm của Lớp học.
Để phục vụ cho mục đích của ví dụ này, hãy sử dụng lại mẫu tệp đính kèm trong hướng dẫn trước. Mẫu này cho thấy hình ảnh của một địa danh nổi tiếng và chú thích có tên của địa danh đó. Hoạt động này bao gồm việc yêu cầu học viên cung cấp tên của địa danh.
Sửa đổi yêu cầu tạo tệp đính kèm
Chuyển đến phần mã mà bạn đã tạo tệp đính kèm content-type trong hướng dẫn trước. Mục chính ở đây là một thực thể của đối tượng AddOnAttachment, trong đó chúng ta đã chỉ định teacherViewUri
, studentViewUri
và title
cho tệp đính kèm.
Mặc dù tất cả tệp đính kèm bổ sung đều yêu cầu 3 trường này, nhưng sự hiện diện hoặc vắng mặt của studentWorkReviewUri
sẽ xác định xem tệp đính kèm đó thuộc loại hoạt động hay loại nội dung. Yêu cầu CREATE
có studentWorkReviewUri
được điền sẵn sẽ trở thành tệp đính kèm thuộc loại hoạt động, trong khi yêu cầu CREATE
không có studentWorkReviewUri
sẽ trở thành tệp đính kèm thuộc loại nội dung.
Thay đổi duy nhất cần thực hiện đối với yêu cầu này là điền vào trường studentWorkReviewUri
. Thêm một tuyến đường có tên phù hợp tại đây; bạn sẽ triển khai tuyến đường này ở bước sau.
Python
Trong ví dụ mà chúng tôi cung cấp, phương thức này nằm trong phương thức create_attachments
trong tệp 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}",
}
Thêm bộ nhớ liên tục cho tệp đính kèm loại nội dung
Ghi lại câu trả lời của học viên đối với hoạt động của chúng ta. Bạn có thể tra cứu sau khi giáo viên xem bài tập đã nộp trong iframe Đánh giá bài tập của học viên.
Thiết lập giản đồ cơ sở dữ liệu cho một Submission
. Ví dụ mà chúng tôi cung cấp yêu cầu học viên nhập tên của địa danh xuất hiện trong một hình ảnh. Do đó, Submission
chứa các thuộc tính sau:
attachment_id
: Giá trị nhận dạng duy nhất của tệp đính kèm. Do Classroom chỉ định và được trả về trong phản hồi khi tạo một tệp đính kèm.submission_id
: Giá trị nhận dạng của bài tập đã nộp của học viên. Được Lớp học giao và trả về trong phản hồigetAddOnContext
trong Chế độ xem của học viên.
student_response
: Câu trả lời do học viên cung cấp.
Python
Mở rộng hoạt động triển khai SQLite và flask_sqlalchemy
từ các bước trước.
Chuyển đến tệp mà bạn đã xác định các bảng trước đó (models.py
nếu bạn đang làm theo ví dụ mà chúng tôi cung cấp). Thêm nội dung sau vào cuối tệp.
# 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))
Nhập lớp Submission
mới vào tệp máy chủ bằng các tuyến xử lý tệp đính kèm.
Sửa đổi tuyến đường trong Chế độ xem của học viên
Tiếp theo, hãy sửa đổi tuyến đường Chế độ xem của học viên trước đó để hiển thị một biểu mẫu nhỏ và chấp nhận dữ liệu đầu vào của học viên. Bạn có thể dùng lại hầu hết mã trong hướng dẫn trước.
Xác định vị trí mã máy chủ cung cấp tuyến đường cho Chế độ xem của học viên. Đây là tuyến đường được chỉ định trong trường studentViewUri
khi tạo tệp đính kèm.
Thay đổi đầu tiên cần thực hiện là trích xuất submissionId
từ phản hồi getAddOnContext
.
Python
Trong ví dụ mà chúng tôi cung cấp, phương thức này nằm trong phương thức load_activity_attachment
trong tệp 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")
Bạn cũng có thể muốn đưa ra yêu cầu để biết trạng thái bài tập đã nộp của học viên.
Phản hồi chứa giá trị SubmissionState
, cho biết các trạng thái như học viên đã mở tệp đính kèm hay chưa hoặc đã nộp bài hay chưa. Điều này có thể hữu ích nếu bạn muốn không cho phép chỉnh sửa bài tập đã nộp hoặc nếu bạn muốn cung cấp thông tin chi tiết cho giáo viên về tiến trình của học viên:
Python
Trong ví dụ mà chúng tôi cung cấp, đây là phần tiếp theo của phương thức load_activity_attachment
ở trên.
# 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()
Cuối cùng, hãy tìm nạp thông tin tệp đính kèm từ cơ sở dữ liệu của chúng tôi và phân phát một biểu mẫu nhập. Biểu mẫu trong ví dụ mà chúng tôi cung cấp bao gồm một trường nhập chuỗi và một nút gửi. Cho học viên xem hình ảnh địa danh và yêu cầu học viên nhập tên của địa danh đó. Sau khi họ phản hồi, hãy ghi lại phản hồi đó vào cơ sở dữ liệu của chúng tôi.
Python
Trong ví dụ mà chúng tôi cung cấp, đây là phần tiếp theo của phương thức load_activity_attachment
ở trên.
# 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)
Để phân biệt giữa các người dùng, hãy cân nhắc việc tắt chức năng gửi và thay vào đó, hãy cho thấy câu trả lời đúng trong Chế độ xem của giáo viên.
Thêm một tuyến đường cho iframe Student Work Review
Cuối cùng, hãy thêm một tuyến đường để phân phát iframe Student Work Review. Tên của tuyến đường này phải khớp với tên được cung cấp cho studentWorkReviewUri
khi tạo một tệp đính kèm. Lộ trình này sẽ mở ra khi giáo viên xem bài tập đã nộp của học viên trong giao diện người chấm điểm của Lớp học.
Bạn sẽ nhận được tham số truy vấn submissionId
khi Classroom mở iframe Đánh giá bài tập của học viên. Sử dụng mã này để truy xuất bài tập của học viên từ cơ sở dữ liệu cục bộ:
Python
Trong ví dụ mà chúng tôi cung cấp, thuộc tính này nằm trong tệp 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)
Kiểm thử tiện ích bổ sung
Lặp lại các bước Kiểm thử tiện ích bổ sung trong hướng dẫn trước. Bạn phải có một tệp đính kèm mà học viên có thể mở.
Hoàn tất các bước sau để kiểm thử tệp đính kèm hoạt động:
- Đăng nhập vào Google Lớp học với tư cách là một trong những người dùng thử nghiệm học viên trong cùng một lớp học với người dùng thử nghiệm giáo viên.
- Chuyển đến thẻ Bài tập trên lớp rồi mở rộng Bài tập kiểm tra.
- Nhấp vào thẻ tệp đính kèm tiện ích bổ sung để mở Chế độ xem của học viên và gửi câu trả lời cho hoạt động.
- Đóng iframe sau khi hoàn tất hoạt động. Bạn có thể nhấp vào nút Nộp bài.
Bạn sẽ không thấy có gì thay đổi trong Lớp học sau khi hoàn tất hoạt động này. Bây giờ, hãy kiểm thử iframe Student Work Review (Kiểm tra bài tập của học viên):
- Đăng nhập vào Lớp học bằng tài khoản người dùng kiểm thử là giáo viên.
- Tìm cột bài tập kiểm tra của bạn trong thẻ Điểm số. Nhấp vào tên bài tập kiểm tra.
- Tìm thẻ cho người dùng học viên kiểm thử. Nhấp vào tệp đính kèm trên thẻ.
Xác nhận rằng học viên đã gửi bài tập chính xác.
Xin chúc mừng! Bạn đã sẵn sàng chuyển sang bước tiếp theo: đồng bộ hoá điểm số của tệp đính kèm.