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

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

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

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

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

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

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

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

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

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

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

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

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