class EditableWatchedResourceModelSerializer(WatchedResourceModelSerializer): watchers = WatchersField(required=False) def restore_object(self, attrs, instance=None): #watchers is not a field from the model but can be attached in the get_queryset of the viewset. #If that's the case we need to remove it before calling the super method watcher_field = self.fields.pop("watchers", None) self.validate_watchers(attrs, "watchers") new_watcher_ids = attrs.pop("watchers", None) obj = super(WatchedResourceModelSerializer, self).restore_object(attrs, instance) #A partial update can exclude the watchers field or if the new instance can still not be saved if instance is None or new_watcher_ids is None: return obj new_watcher_ids = set(new_watcher_ids) old_watcher_ids = set(obj.get_watchers().values_list("id", flat=True)) adding_watcher_ids = list(new_watcher_ids.difference(old_watcher_ids)) removing_watcher_ids = list( old_watcher_ids.difference(new_watcher_ids)) User = get_user_model() adding_users = get_user_model().objects.filter( id__in=adding_watcher_ids) removing_users = get_user_model().objects.filter( id__in=removing_watcher_ids) for user in adding_users: services.add_watcher(obj, user) for user in removing_users: services.remove_watcher(obj, user) obj.watchers = obj.get_watchers() return obj def to_native(self, obj): #if watchers wasn't attached via the get_queryset of the viewset we need to manually add it if obj is not None: if not hasattr(obj, "watchers"): obj.watchers = [user.id for user in obj.get_watchers()] request = self.context.get("request", None) user = request.user if request else None if user and user.is_authenticated(): obj.is_watcher = user.id in obj.watchers return super(WatchedResourceModelSerializer, self).to_native(obj) def save(self, **kwargs): obj = super(EditableWatchedResourceModelSerializer, self).save(**kwargs) self.fields["watchers"] = WatchersField(required=False) obj.watchers = [user.id for user in obj.get_watchers()] return obj
class WatchedResourceModelSerializer(serializers.ModelSerializer): is_watched = serializers.SerializerMethodField("get_is_watched") watchers = WatchersField(required=False) def get_is_watched(self, obj): # The "is_watched" attribute is attached in the get_queryset of the viewset. return getattr(obj, "is_watched", False) or False def restore_object(self, attrs, instance=None): #watchers is not a field from the model but can be attached in the get_queryset of the viewset. #If that's the case we need to remove it before calling the super method watcher_field = self.fields.pop("watchers", None) instance = super(WatchedResourceModelSerializer, self).restore_object(attrs, instance) if instance is not None and self.validate_watchers(attrs, "watchers"): #A partial update can exclude the watchers field if not "watchers" in attrs: return instance new_watcher_ids = set(attrs.get("watchers", None)) old_watcher_ids = set(instance.get_watchers().values_list( "id", flat=True)) adding_watcher_ids = list( new_watcher_ids.difference(old_watcher_ids)) removing_watcher_ids = list( old_watcher_ids.difference(new_watcher_ids)) User = apps.get_model("users", "User") adding_users = User.objects.filter(id__in=adding_watcher_ids) removing_users = User.objects.filter(id__in=removing_watcher_ids) for user in adding_users: services.add_watcher(instance, user) for user in removing_users: services.remove_watcher(instance, user) instance.watchers = instance.get_watchers() return instance def to_native(self, obj): #watchers is wasn't attached via the get_queryset of the viewset we need to manually add it if obj is not None and not hasattr(obj, "watchers"): obj.watchers = [user.id for user in obj.get_watchers()] return super(WatchedResourceModelSerializer, self).to_native(obj) def save(self, **kwargs): obj = super(WatchedResourceModelSerializer, self).save(**kwargs) self.fields["watchers"] = WatchersField(required=False) obj.watchers = [user.id for user in obj.get_watchers()] return obj
def save(self, **kwargs): obj = super(EditableWatchedResourceSerializer, self).save(**kwargs) self.fields["watchers"] = WatchersField(required=False) obj.watchers = [user.id for user in obj.get_watchers()] return obj