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

هذا هو العرض التوضيحي الخامس في سلسلة العروض التوضيحية الخاصة بإضافات Classroom.

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

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

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

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

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

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

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

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

انتقِل إلى قسم الرمز الذي أنشأت فيه مرفقًا من نوع المحتوى في الشرح السابق. العنصر الأساسي هنا هو مثيل لكائن AddOnAttachment، والذي حدّدنا فيه سابقًا 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 بصفتك معلّمًا مستخدمًا تجريبيًا.
  • ابحث عن عمود مهمة الاختبار في علامة التبويب الدرجات. انقر على اسم مهمة الاختبار.
  • ابحث عن بطاقة مستخدم الطالب التجريبي. انقر على المرفق في البطاقة.

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

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