مرفقات نوع النشاط

هذه هي الجولة التفصيلية الخامسة ضمن سلسلة الجولة التفصيلية حول إضافات Classroom.

في هذه الجولة التفصيلية، عدّلت المثال من الخطوة التفصيلية السابقة لإنشاء مرفق يتضمّن نوع النشاط. يشمل ذلك أي مرفقات تتطلب أن يرسل الطالب ردًّا مكتوبًا أو اختبارًا أو أي أداة أخرى من إنشاء الطالب.

من المهم التمييز بين المرفقات من نوع المحتوى ونوع النشاط. تختلف المرفقات من نوع النشاط عن نوع المحتوى في النقاط التالية:

  • يظهر زر "تسليم" في أعلى يسار إطار iframe الخاص بعرض الطلاب.
  • توفر معرّفًا فريدًا لعمل الطالب.
  • وتظهر بطاقة المرفق في واجهة مستخدم معلِّمي الصفوف في Classroom.
  • ويمكنهم تعيين درجة للمهمة التي ينتمون إليها.

اطّلِع على الجولة التفصيلية التالية للنقاش حول وضع الدرجات. خلال هذه الجولة، تكمل ما يلي:

  • يمكنك تعديل طلبات إنشاء المرفقات السابقة إلى Classroom API لإنشاء مرفق نوع النشاط.
  • استخدام مساحة تخزين دائمة لعمليات الإرسال التي يرسلها الطلاب
  • يمكنك تعديل مسار "عرض الطلاب" السابق لقبول إدخالات الطلاب.
  • يمكنك توفير مسار لعرض إطار iframe لمراجعة عمل الطلاب.

بعد الانتهاء، يمكنك إنشاء مرفقات من نوع النشاط في المهام الدراسية من خلال واجهة مستخدم Google Classroom عند تسجيل الدخول كمعلّم. ويمكن للطلاب في الصف أيضًا إكمال النشاط في إطار iframe وإرسال رد. يمكن للمعلم عرض المحتوى الذي أرسله الطالب في واجهة المستخدم لوضع الدرجات في Classroom.

لأغراض هذا المثال، أعد استخدام قالب المرفق من الجولة التفصيلية السابقة التي تعرض صورة لمعلم شهير وتسمية توضيحية باسم المَعلم. يتكون النشاط من مطالبة الطالب بتقديم اسم المَعلم.

تعديل طلب إنشاء المرفق

انتقل إلى قسم التعليمة البرمجية الذي أنشأت فيه مرفقًا بنوع المحتوى في الجولة التفصيلية السابقة. يُعد العنصر الرئيسي هنا مثيلاً للكائن AddOnAttach، والذي حدّدنا فيه سابقًا teacherViewUri وstudentViewUri وtitle للمرفق.

على الرغم من أنّ جميع مرفقات الإضافات تتطلّب هذه الحقول الثلاثة، إنّ توفّر studentWorkReviewUri أو عدم إدراجه يحدّد ما إذا كان المرفق من نوع النشاط أو المحتوى. إنّ طلب CREATE الذي يحتوي على studentWorkReviewUri تمت تعبئته يصبح مرفقًا بنوع نشاط، بينما يصبح الطلب CREATE بدون studentWorkReviewUri مرفقًا بنوع محتوى.

التعديل الوحيد الذي يتم إجراؤه على هذا الطلب هو ملء الحقل 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: معرّف فريد لمرفق يتم تعيينه من قِبل Classroom ويتم عرضه في الرد عند إنشاء مرفق.
  • submission_id: معرّف لإرسال الطالب تم تعيينه من قِبل Classroom وتم عرضه في استجابة 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 عند إنشاء مُرفق. أول تغيير يجب إجراؤه هو استخراج السمة submissionId من الاستجابة getAddOnContext.

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 عند إنشاء مُرفق. يتم فتح هذا المسار عندما يعرض المعلم الطلب الذي أرسله الطالب في واجهة مستخدم طلاب Classroom.

تتلقّى معلَمة طلب البحث submissionId عندما يفتح Classroom إطار 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)

اختبار الإضافة

كرِّر اختبار خطوات الإضافة من الجولة التفصيلية السابقة. يجب أن يكون لديك مرفق يمكن للطالب فتحه.

أكمل الخطوات التالية لاختبار مرفق النشاط:

  • سجِّل الدخول إلى Google Classroom بصفتك أحد مستخدمي الطلاب المختبِرين في الصف نفسه الذي يحمله المستخدم المختبِر للمعلّم.
  • انتقِل إلى علامة التبويب الواجب الدراسي ووسِّع مهمة للاختبار.
  • انقر على بطاقة مرفق الإضافة لفتح "طريقة عرض الطلاب" وإرسال رد على النشاط.
  • أغلق إطار iframe بعد إكمال النشاط. انقر على الزر تسليم، إذا رغبت في ذلك.

من المفترض ألا تلاحظ أي تغيير في Classroom بعد إكمال النشاط. يمكنك الآن اختبار إطار iframe لمراجعة عمل الطلاب:

  • سجِّل الدخول إلى Classroom بصفتك مستخدم اختبار المعلّم.
  • ابحث عن عمود المهمة الاختبارية في علامة التبويب الدرجات. انقر فوق اسم المهمة التجريبية.
  • ابحث عن بطاقة المستخدم الطالب للاختبار. انقر على المرفق في البطاقة.

تأكَّد من ظهور المشاركة الصحيحة للطالب.

تهانينا يمكنك الآن المتابعة إلى الخطوة التالية: مزامنة درجات المرفقات.