|
76 | 76 | from webob import Response
|
77 | 77 | from web_fragments.fragment import Fragment
|
78 | 78 | from xblock.core import List, Scope, String, XBlock
|
79 |
| -from xblock.fields import Boolean, Float |
| 79 | +from xblock.fields import Boolean, Float, UserScope |
80 | 80 | try:
|
81 | 81 | from xblock.utils.resources import ResourceLoader
|
82 | 82 | from xblock.utils.studio_editable import StudioEditableXBlockMixin
|
@@ -1017,3 +1017,41 @@ def is_past_due(self):
|
1017 | 1017 | else:
|
1018 | 1018 | close_date = due_date
|
1019 | 1019 | return close_date is not None and datetime.datetime.now(UTC) > close_date
|
| 1020 | + |
| 1021 | + def bind_for_student(self, user_id, wrappers=None): |
| 1022 | + """ |
| 1023 | + Bind the XBlock to a specific student by user_id. |
| 1024 | +
|
| 1025 | + Arguments: |
| 1026 | + user_id: The user_id to set in scope_ids. |
| 1027 | + wrappers: A list of functions to wrap the field data, if any. |
| 1028 | + """ |
| 1029 | + # If we're already bound to this user, skip re-binding |
| 1030 | + if self.scope_ids.user_id is not None and user_id == self.scope_ids.user_id: |
| 1031 | + return |
| 1032 | + |
| 1033 | + # Update scope_ids to the new user |
| 1034 | + self.scope_ids = self.scope_ids._replace(user_id=user_id) |
| 1035 | + |
| 1036 | + # Clear cached child data |
| 1037 | + self.clear_child_cache() |
| 1038 | + |
| 1039 | + # Clear cached field data |
| 1040 | + for field in self.fields.values(): |
| 1041 | + if field.scope.user == UserScope.ONE: |
| 1042 | + field._del_cached_value(self) |
| 1043 | + if field in self._dirty_fields: |
| 1044 | + del self._dirty_fields[field] |
| 1045 | + |
| 1046 | + # Apply wrappers if provided |
| 1047 | + if wrappers: |
| 1048 | + wrapped_field_data = self.runtime.service(self, 'field-data-unbound') |
| 1049 | + for wrapper in wrappers: |
| 1050 | + wrapped_field_data = wrapper(wrapped_field_data) |
| 1051 | + self._bound_field_data = wrapped_field_data |
| 1052 | + |
| 1053 | + if getattr(self.runtime, "uses_deprecated_field_data", False): |
| 1054 | + self._field_data = wrapped_field_data |
| 1055 | + |
| 1056 | + # Optionally save the state if needed |
| 1057 | + self.save() |
0 commit comments