To piąta instrukcja z serii instrukcji dotyczących dodatków do Classroom.
W tym przewodniku zmodyfikujesz przykład z poprzedniego kroku, aby utworzyć załącznik typu aktywność. Są to wszystkie załączniki, które wymagają przesłania przez ucznia, np. pisemnej odpowiedzi, testu lub innego wytworu ucznia.
Rozróżnienie między załącznikami typu treść a załącznikami typu aktywność jest ważne. Załączniki typu aktywności różnią się od załączników typu treści w tych aspektach:
- W prawym górnym rogu elementu iframe Widok ucznia pojawi się przycisk „Prześlij”.
- Zawierają one niepowtarzalny identyfikator pracy ucznia.
- Karta załącznika pojawi się w interfejsie narzędzia do oceniania w Classroom.
- Mogą ustawić ocenę projektu, do którego należą.
Więcej informacji o ocenianiu znajdziesz w następnym przewodniku. W ramach tego przewodnika wykonasz te czynności:
- Zmodyfikuj poprzednie żądania utworzenia załącznika w interfejsie Classroom API, aby utworzyć załącznik typu aktywność.
- Wdrożenie pamięci trwałej dla przesłanych prac uczniów.
- Zmodyfikuj poprzednią trasę widoku ucznia, aby akceptować dane wejściowe ucznia.
- Podaj ścieżkę do wyświetlania elementu iframe Sprawdzanie zadań uczniów.
Po zakończeniu możesz tworzyć załączniki typu aktywność w projektach w interfejsie Google Classroom po zalogowaniu się jako nauczyciel. Uczniowie w klasie mogą również wykonać ćwiczenie w elemencie iframe i przesłać odpowiedź. Nauczyciel może wyświetlić zadanie ucznia w interfejsie oceniania Classroom.
Na potrzeby tego przykładu użyj ponownie szablonu załącznika z poprzedniego przewodnika, który zawiera obraz znanego zabytku i podpis z jego nazwą. Zadanie polega na poproszeniu ucznia o podanie nazwy punktu orientacyjnego.
Zmiana prośby o utworzenie załącznika
Przejdź do sekcji kodu, w której w poprzednim przewodniku utworzono załącznik content-type. Kluczowym elementem jest tu instancja obiektu AddOnAttachment, w której wcześniej określiliśmy atrybuty teacherViewUri
, studentViewUri
i title
załącznika.
Wszystkie załączniki dodatków wymagają tych 3 pól, ale obecność lub brak studentWorkReviewUri
decyduje o tym, czy załącznik jest typu aktywności czy typu treści. CREATE
Prośba z wypełnionym polem studentWorkReviewUri
staje się załącznikiem typu aktywność, a CREATE
prośba bez wypełnionego pola studentWorkReviewUri
staje się załącznikiem typu treść.
Jedyną zmianą, jaką należy wprowadzić w tym żądaniu, jest wypełnienie pola studentWorkReviewUri
. Dodaj tutaj odpowiednio nazwaną trasę. Zaimplementujesz ją w późniejszym kroku.
Python
W naszym przykładzie jest to metoda create_attachments
w pliku 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}",
}
Dodawanie trwałej pamięci masowej do załączników typu treści
Zarejestruj odpowiedź ucznia na nasze działanie. Możesz go później sprawdzić, gdy nauczyciel wyświetli przesłane zadanie w ramce iframe Sprawdzanie prac uczniów.
Skonfiguruj schemat bazy danych dla Submission
. W podanym przykładzie oczekujemy, że uczniowie wpiszą nazwę punktu orientacyjnego widocznego na obrazie. Submission
zawiera więc te atrybuty:
attachment_id
: unikalny identyfikator załącznika. Przypisany przez Classroom i zwracany w odpowiedzi podczas tworzenia załącznika.submission_id
: Identyfikator przesłanego przez ucznia zadania. Przypisane przez Classroom i zwrócone wgetAddOnContext
odpowiedzi w widoku ucznia.
student_response
: odpowiedź podana przez ucznia.
Python
Rozszerz implementację SQLite i flask_sqlalchemy
z poprzednich kroków.
Otwórz plik, w którym zdefiniowano poprzednie tabele (models.py
jeśli korzystasz z naszego przykładu). Na końcu pliku dodaj te wiersze:
# 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))
Zaimportuj nową klasę Submission
do pliku serwera z trasami obsługi załączników.
Modyfikowanie trasy w widoku ucznia
Następnie zmodyfikuj poprzednią ścieżkę widoku ucznia, aby wyświetlić mały formularz i zaakceptować dane wejściowe od ucznia. Możesz ponownie wykorzystać większość kodu z poprzedniego przewodnika.
Znajdź kod serwera, który określa trasę dla widoku ucznia. Jest to ścieżka określona w polu studentViewUri
podczas tworzenia załącznika.
Pierwszą zmianą, którą należy wprowadzić, jest wyodrębnienie submissionId
z getAddOnContext
odpowiedzi.
Python
W podanym przykładzie jest to metoda load_activity_attachment
w pliku 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")
Możesz też wysłać prośbę o uzyskanie stanu przesłania przez ucznia.
Odpowiedź zawiera wartość SubmissionState
, która wskazuje stany, takie jak otwarcie załącznika przez ucznia lub przesłanie go. Może to być przydatne, jeśli chcesz uniemożliwić edytowanie oddanego projektu lub jeśli chcesz, aby nauczyciele mieli wgląd w postępy uczniów:
Python
W podanym przykładzie jest to kontynuacja metody load_activity_attachment
powyżej.
# 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()
Na koniec pobierz informacje o załączniku z naszej bazy danych i wyświetl formularz wejściowy. Formularz w naszym przykładzie składa się z pola wprowadzania ciągu znaków i przycisku przesyłania. Wyświetl obraz punktu orientacyjnego i poproś ucznia o wpisanie jego nazwy. Gdy użytkownik odpowie, zapisz jego odpowiedź w naszej bazie danych.
Python
W podanym przykładzie jest to kontynuacja metody load_activity_attachment
powyżej.
# 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)
Aby odróżnić użytkowników, możesz wyłączyć funkcję przesyłania i zamiast tego wyświetlić prawidłową odpowiedź w widoku nauczyciela.
Dodawanie trasy do elementu iframe sprawdzania zadań uczniów
Na koniec dodaj ścieżkę do wyświetlania elementu iframe z informacjami o sprawdzaniu prac uczniów. Nazwa tej trasy powinna być zgodna z nazwą podaną w przypadku parametru studentWorkReviewUri
podczas tworzenia załącznika. Ta ścieżka otwiera się, gdy nauczyciel wyświetla projekt przesłany przez ucznia w interfejsie oceniania w Classroom.
Parametr zapytania submissionId
otrzymasz, gdy Classroom otworzy ramkę iframe sprawdzania zadań uczniów. Użyj go, aby pobrać pracę ucznia z lokalnej bazy danych:
Python
W naszym przykładzie jest to plik 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)
Testowanie dodatku
Powtórz kroki testowania dodatku z poprzedniego przewodnika. Powinien zawierać załącznik, który uczeń może otworzyć.
Aby przetestować załącznik do aktywności:
- Zaloguj się w Google Classroom jako jeden z uczniów testowych w tej samej klasie co nauczyciel testowy.
- Przejdź na kartę Zadania i rozwiń projekt testowy.
- Kliknij kartę załącznika dodatku, aby otworzyć widok ucznia i przesłać odpowiedź na aktywność.
- Po zakończeniu aktywności zamknij element iframe. Opcjonalnie kliknij przycisk Prześlij.
Po wykonaniu zadania nie powinny wystąpić żadne zmiany w Classroom. Teraz przetestuj element iframe sprawdzania zadań uczniów:
- Zaloguj się w Classroom jako nauczyciel testowy.
- Na karcie Oceny znajdź kolumnę z oceną za test. Kliknij nazwę testu.
- Znajdź kartę testowego użytkownika-ucznia. Kliknij załącznik na karcie.
Sprawdź, czy uczeń widzi prawidłowe przesłane zadanie.
Gratulacje! Możesz przejść do następnego kroku: synchronizowania ocen załączników.