class CollectionSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) title = serializers.CharField(required=True) description = serializers.CharField(required=False, allow_blank=True) tags = serializers.CharField(required=False, allow_blank=True) settings = serializers.JSONField(required=False) submission_settings = serializers.JSONField(required=False) created_by_org = serializers.CharField(allow_blank=True, required=False) created_by = RelationshipField( related_view='user-detail', related_view_kwargs={'user_id': '<created_by.pk>'}, ) date_created = serializers.DateTimeField(read_only=True) date_updated = serializers.DateTimeField(read_only=True) groups = RelationshipField(related_view='collection-group-list', related_view_kwargs={'pk': '<pk>'}) items = RelationshipField(related_view='collection-item-list', related_view_kwargs={'pk': '<pk>'}) class Meta: model = Collection fields = ['id', 'title', 'description', 'tags', 'created_by'] class JSONAPIMeta: resource_name = 'collections' def create(self, validated_data): user = self.context['request'].user collection = Collection.objects.create(created_by=user, **validated_data) assign_perm('api.approve_collection_items', user, collection) return collection def update(self, collection, validated_data): collection.title = validated_data.get('title', collection.title) collection.description = validated_data.get('description', collection.description) collection.tags = validated_data.get('tags', collection.tags) collection.settings = validated_data.get('settings', collection.settings) collection.submission_settings = validated_data.get( 'submission_settings', collection.submission_settings) collection.created_by_org = validated_data.get( 'created_by_org', collection.created_by_org) collection.save() return collection
class ComponentSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Component fields = ('url', 'name', 'description', 'attributes') read_only_fields = ('project', ) url = relations.NestedHyperlinkedIdentityField( view_name='component-detail', parent_lookup_kwargs={'project_slug': 'project__slug'}) attributes = serializers.JSONField(default=list)
class RobotRetrieveSerializer(serializers.ModelSerializer): included_serializers = { "exchange": ExchangeSerializer, "asset_record": AssetRecordSerializer, "user": UserSerializer, } user = UserSerializer(source="credential.user", read_only=True) exchange = ExchangeSerializer(source="credential.exchange", read_only=True) duration_display = DurationField(source="duration", read_only=True) asset_record = AssetRecordSerializer(read_only=True) strategy_parameters = serializers.JSONField(read_only=True) strategy_parameters_view = serializers.SerializerMethodField() class Meta: model = Robot fields = [ "id", "name", "pair", "target_currency", "base_currency", "quote_currency", "enabled", "start_time", "ping_time", "duration_display", "asset_record", "credential", "strategy_parameters", "strategy_parameters_view", "user", "exchange", "created_at", "modified_at", ] read_only_fields = [ "ping_time", "created_at", "modified_at", ] extra_kwargs = { "credential": {"write_only": True}, } class JSONAPIMeta: resource_name = "robots" included_resources = ["exchange", "asset_record", "user"] def get_strategy_parameters_view(self, obj: Robot) -> Dict[str, Any]: spec = obj.strategy.specification parameters = obj.strategy_parameters for parameter in spec["parameters"]: parameter["value"] = parameters[parameter["code"]] return spec
class ChartTypeSerializer(serializers.ModelSerializer): class Meta: model = ChartType # Specify the fields explicitly to include m2m (filter_groups). fields = [ 'id', 'name', 'format_spec', 'order_ascending', 'game', 'filter_groups' ] # Serialize format spec as a JSON encoded string, rather than a primitive # data structure. format_spec = serializers.JSONField(binary=True)
class LinkSerializer(BaseInternalModelSerializer): url = serializers.URLField(), group = ResourceRelatedField(many=False, queryset=Group.objects) page = ResourceRelatedField(many=False, queryset=Page.objects) scraped_data = serializers.JSONField() included_serializers = {'group': GroupSerializer, 'page': PageSerializer} class Meta: model = Link fields = ('id', 'metadata', 'created', 'modified', 'scraped_data') read_only_fields = ('id', ) class JSONAPIMeta: included_resources = ['page', 'group']
class UpdateSerializer(BaseInternalModelSerializer): user = ResourceRelatedField(many=False, queryset=get_user_model().objects) included_serializers = { 'group': AnonGroupSerializer, 'page': PageSerializer, 'user': '******', 'files': FileSerializer, 'wrappers': 'proposals.api.app.serializers.WrapperSerializer' } group = ResourceRelatedField(many=False, queryset=Group.objects) page = ResourceRelatedField( pk_field=HashidSerializerCharField(source_field='groups.Page.id'), queryset=Page.objects.all(), many=False) organization = ResourceRelatedField(many=False, queryset=Organization.objects) files = ResourceRelatedField(many=True, queryset=File.objects, required=False) links = ResourceRelatedField(many=True, queryset=Link.objects, required=False) wrappers = ResourceRelatedField(many=True, queryset=Wrapper.objects, required=False) reports = ResourceRelatedField(many=True, queryset=Report.objects, required=False) document = serializers.JSONField(required=False) class Meta: model = Update fields = ('id', 'user', 'group', 'organization', 'page', 'document', 'title', 'published', 'reports', 'wrappers', 'files', 'links', 'created', 'modified') class JSONAPIMeta: included_resources = [ 'user', 'page', 'page.organization', 'group', 'files', 'wrappers', 'wrappers.bill', 'wrappers.bill.sponsor' ]
class RobotConfigSerializer(serializers.ModelSerializer): user = UserSerializer(source="credential.user", read_only=True) exchange = ExchangeSerializer(source="credential.exchange", read_only=True) credential_keys = CredentialKeysSerializer(source="credential", read_only=True) test_net = serializers.BooleanField(source="credential.test_net", read_only=True) strategy_parameters = serializers.JSONField() class Meta: model = Robot fields = [ "id", "name", "pair", "target_currency", "enabled", "test_net", "user", "exchange", "credential_keys", "strategy_parameters", ] class JSONAPIMeta: resource_name = "robot_configs"
class ItemSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) source_id = serializers.CharField() title = serializers.CharField(required=True) type = serializers.ChoiceField( choices=['project', 'preprint', 'registration', 'meeting', 'website']) status = serializers.ChoiceField( choices=['approved', 'pending', 'rejected']) url = serializers.URLField() created_by = UserSerializer(read_only=True) metadata = serializers.JSONField(required=False) date_added = serializers.DateTimeField(read_only=True, allow_null=True) date_submitted = serializers.DateTimeField(read_only=True) class Meta: model = Item class JSONAPIMeta: resource_name = 'items' def create(self, validated_data): user = self.context['request'].user collection_id = self.context.get( 'collection_id', None) or self.context['request'].parser_context['kwargs'].get( 'pk', None) collection = Collection.objects.get(id=collection_id) allow_all = None if collection.settings: collection_settings = json.loads(collection.settings) allow_all = collection_settings.get('allow_all', None) collection_type = collection_settings.get('type', None) if collection_type and validated_data['type'] != collection_type: raise ValueError('Collection only accepts items of type ' + collection_type) status = 'pending' if user.has_perm('api.approve_items', collection) or allow_all: status = 'approved' validated_data['date_added'] = timezone.now() group_id = self.context.get( 'group_id', None) or self.context['request'].parser_context['kwargs'].get( 'group_id', None) if group_id: validated_data['group'] = Group.objects.get(id=group_id) validated_data['status'] = status item = Item.objects.create(created_by=user, collection=collection, **validated_data) return item def update(self, item, validated_data): user = self.context['request'].user status = validated_data.get('status', item.status) collection_id = self.context.get( 'collection_id', None) or self.context['request'].parser_context['kwargs'].get( 'pk', None) if collection_id: collection = Collection.objects.get(id=collection_id) else: collection = item.collection if status != item.status and user.has_perm('api.approve_items', collection): raise exceptions.PermissionDenied( detail='Cannot change submission status.') elif user.id != item.created_by_id and validated_data.keys() != [ 'status' ]: raise exceptions.PermissionDenied( detail='Cannot update another user\'s submission.') group_id = self.context.get( 'group_id', None) or self.context['request'].parser_context['kwargs'].get( 'group_id', None) if group_id: group = Group.objects.get(id=group_id) else: group = None item_type = validated_data.get('type', item.type) if collection.settings: collection_settings = json.loads(collection.settings) collection_type = collection_settings.get('type', None) if collection_type and item_type != collection_type: raise ValueError('Collection only accepts items of type ' + collection_type) item.group = group item.source_id = validated_data.get('source_id', item.source_id) item.title = validated_data.get('title', item.title) item.type = item_type item.status = status item.url = validated_data.get('url', item.url) item.metadata = validated_data.get('metadata', item.metadata) item.save() return item
class UserProfileSerializer(serializers.ModelSerializer): """ Serializer class for UserProfile model """ first_name = serializers.CharField(source="user.first_name") last_name = serializers.CharField(source="user.last_name") email = serializers.EmailField(source="user.email") password = serializers.CharField( source="user.password", allow_null=True, default=None, required=False, write_only=True, ) last_login = serializers.DateTimeField( source="user.last_login", read_only=True) submission_count = serializers.SerializerMethodField() amount_earned = SerializableAmountField(read_only=True) avg_amount_earned = SerializableAvgAmountEarnedField(read_only=True) metadata = serializers.JSONField(read_only=True) class Meta: # pylint: disable=too-few-public-methods """ class meta options """ model = UserProfile fields = [ "id", "created", "modified", "role_display", "gender_display", "expertise_display", "first_name", "last_name", "password", "email", "ona_pk", "ona_username", "payment_number", "approved_submissions", "rejected_submissions", "approval_rate", "amount_earned", "last_login", "avg_submissions", "avg_approved_submissions", "avg_rejected_submissions", "avg_approval_rate", "avg_amount_earned", "phone_number", "role", "expertise", "gender", "national_id", "submission_count", "address", "metadata", ] owner_only_fields = ("metadata", ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.instance and hasattr(self.Meta, "owner_only_fields"): request = self.context.get("request") is_permitted = (request and request.user and request.user == self.instance.user) if isinstance(self.instance, QuerySet) or not is_permitted or not request: for field in getattr(self.Meta, "owner_only_fields"): self.fields.pop(field) def get_submission_count(self, obj): # pylint: disable=no-self-use """ Get the submission count """ return obj.user.submission_set.count() def validate_password(self, value): """ Custom validation for Password Field """ if not self.instance: # On create of a new user Password shouldn't be none if value is None: raise serializers.ValidationError(NEED_PASSWORD_ON_CREATE) if value is not None: validate_password(value) return value def create(self, validated_data): """ Custom create method to create User object then UserProfile object """ user_data = validated_data.pop("user") user_data["username"] = validated_data.get("ona_username") first_name = user_data.get("first_name") last_name = user_data.get("last_name") email = user_data.get("email") password = user_data.get("password") created, data = create_ona_user( settings.ONA_BASE_URL, user_data["username"], first_name, last_name, email, password, ) if not created: raise serializers.ValidationError(data) if not data: raise serializers.ValidationError(CANNOT_ACCESS_ONADATA) ona_pk = data.get("id") metadata = data.get("metadata") add_team_member(settings.ONA_BASE_URL, user_data["username"], settings.ONA_MEMBERS_TEAM_ID) # make user an admin of organisation at ona if validated_data.get("role") == UserProfile.ADMIN: updated = change_user_role( settings.ONA_BASE_URL, settings.ONA_ORG_NAME, user_data["username"], settings.ONA_OWNER_ROLE, ) if not updated: # default to contributor role incase admin fails validated_data["role"] = UserProfile.CONTRIBUTOR elif validated_data["role"] == UserProfile.CONTRIBUTOR: change_user_role( settings.ONA_BASE_URL, settings.ONA_ORG_NAME, user_data["username"], settings.ONA_CONTRIBUTER_ROLE, ) # set an unusable password by not passing the password to the create # method. Why, you ask? Because we don't want to store passwords # on the Kaznet site. Ona is the source of truth for this. try: del user_data["password"] except KeyError: pass # create the User object user = UserSerializer.create( UserSerializer(), validated_data=user_data) # populate the UserProfile object userprofile = user.userprofile userprofile.ona_pk = ona_pk userprofile.ona_username = user.username userprofile.payment_number = validated_data.get("payment_number") userprofile.phone_number = validated_data.get("phone_number") if validated_data.get("role"): userprofile.role = validated_data.get("role") userprofile.gender = validated_data.get("gender") if validated_data.get("national_id"): userprofile.national_id = validated_data.get("national_id") userprofile.expertise = validated_data.get("expertise") if metadata: userprofile.metadata["last_password_edit"] = metadata.get( settings.ONA_LAST_PASSWORD_EDIT_FIELD) userprofile.metadata["gravatar"] = data.get("gravatar") userprofile.save() return userprofile # pylint: disable=too-many-branches, too-many-statements def update(self, instance, validated_data): """ Custom update method for UserProfiles """ # deal with the user object user = instance.user user_data = validated_data.pop("user") username = user.username first_name = user_data.get("first_name") last_name = user_data.get("last_name") data = {} # you can't change username try: del user_data["username"] except KeyError: pass # you can't change email # this is because Onadata requires your current password when changing # the email. And we cannot get the user's current password try: del user_data["email"] except KeyError: pass # you can't change password # this is because Onadata requires your current password when changing # the password. And we cannot get the user's current password try: del user_data["password"] except KeyError: pass # only pick changed values significant to ona profile update_data = {} if first_name != instance.user.first_name: update_data["first_name"] = first_name if last_name != instance.user.last_name: update_data["last_name"] = last_name # update on ona only if there is are changes made significant to ona if any(update_data): updated, data = update_details(settings.ONA_BASE_URL, username, update_data) if not updated: raise serializers.ValidationError(data) if not data: raise serializers.ValidationError(CANNOT_ACCESS_ONADATA) # change role to admin if the user is not initially an admin if (validated_data.get("role") == UserProfile.ADMIN and instance.role != UserProfile.ADMIN): updated = change_user_role( settings.ONA_BASE_URL, settings.ONA_ORG_NAME, username, settings.ONA_OWNER_ROLE, ) if not updated: # default to previous role incase change to admin fails validated_data["role"] = instance.role # change role to contributor if user was admin initially elif (validated_data.get("role") != UserProfile.ADMIN and instance.role == UserProfile.ADMIN): updated = change_user_role( settings.ONA_BASE_URL, settings.ONA_ORG_NAME, username, settings.ONA_CONTRIBUTER_ROLE, ) if not updated: # default to previous role incase change to contributor fails validated_data["role"] = instance.role UserSerializer().update(instance=user, validated_data=user_data) # deal with the userprofile object instance.payment_number = validated_data.get("payment_number", instance.payment_number) instance.phone_number = validated_data.get("phone_number", instance.phone_number) instance.role = validated_data.get("role", instance.role) instance.gender = validated_data.get("gender", instance.gender) if instance.national_id: instance.national_id = validated_data.get("national_id", instance.national_id) instance.expertise = validated_data.get("expertise", instance.expertise) if any(data): metadata = data.get("metadata") gravatar = data.get("gravatar") try: instance.metadata["last_password_edit"] = metadata.get( settings.ONA_LAST_PASSWORD_EDIT_FIELD) except AttributeError: pass instance.metadata["gravatar"] = gravatar instance.save() return instance
class EventSerializer(serializers.ModelSerializer): """ { "address": "0x25Ff5dc79A7c4e34254ff0f4a19d69E491201DD3", "blockNumber": 3, "transactionHash": "0xc18a24a35052a5a3375ee6c2c5ddd6b0587cfa950b59468b67f63f284e2cc382", "transactionIndex": 0, "blockHash": "0x62469a8d113b27180c139d88a25f0348bb4939600011d33382b98e10842c85d9", "logIndex": 0, "removed": false, "id": "log_25652065", "returnValues": { "0": "0xFCaf25bF38E7C86612a25ff18CB8e09aB07c9885", "shipTokenContractAddress": "0xFCaf25bF38E7C86612a25ff18CB8e09aB07c9885" }, "event": "SetTokenContractAddressEvent", "signature": "0xbbbf32f08c8c0621e580dcf0a8e0024525ec357db61bb4faa1a639d4f958a824", "raw": { "data": "0x000000000000000000000000fcaf25bf38e7c86612a25ff18cb8e09ab07c9885", "topics": [ "0xbbbf32f08c8c0621e580dcf0a8e0024525ec357db61bb4faa1a639d4f958a824" ] } } """ block_hash = serializers.CharField(source='blockHash') block_number = serializers.IntegerField(source='blockNumber') log_index = serializers.IntegerField(source='logIndex') event_id = serializers.CharField(source='id') return_values = serializers.JSONField(source='returnValues') event_name = serializers.CharField(source='event') raw = serializers.JSONField() transaction_hash = serializers.CharField(source='transactionHash') transaction_index = serializers.IntegerField(source='transactionIndex') class Meta: model = Event fields = [ 'block_hash', 'block_number', 'log_index', 'event_id', 'return_values', 'event_name', 'transaction_hash', 'transaction_index', 'removed', 'signature', 'raw', 'address' ] def to_internal_value(self, data): if 'blockHash' in data: data['block_hash'] = data['blockHash'] if 'blockNumber' in data: data['block_number'] = data['blockNumber'] if 'logIndex' in data: data['log_index'] = data['logIndex'] if 'id' in data: data['event_id'] = data['id'] if 'returnValues' in data: data['return_values'] = data['returnValues'] if 'event' in data: data['event_name'] = data['event'] if 'transactionHash' in data: data['transaction_hash'] = data['transactionHash'] if 'transactionIndex' in data: data['transaction_index'] = data['transactionIndex'] return super(EventSerializer, self).to_internal_value(data)
class ExtraDataSerializer(BaseShareSerializer): data = serializers.JSONField() class Meta(BaseShareSerializer.Meta): links = () model = models.ExtraData
class AnnotationSerializer(serializers.ModelSerializer): file = relations.ResourceRelatedField(read_only=True) author = relations.ResourceRelatedField(read_only=True) selectors = serializers.JSONField() favorited = serializers.SerializerMethodField() favoritesCount = serializers.SerializerMethodField( method_name='get_favorites_count') # tagList = relations.ResourceRelatedField(many=True, read_only=True) # tags = relations.ResourceRelatedField(many=True, queryset=Tag.objects.all(), allow_null=True) # 自定义方法来处理关系 tags = TagRelatedField(many=True, required=False) comments = relations.ResourceRelatedField( many=True, read_only=True, related_link_view_name='annotation-comments', related_link_url_kwarg='annotation_pk', # TODO 暂时未发现实用性 # self_link_view_name='annotation-relationships' ) createdAt = serializers.SerializerMethodField(method_name='get_created_at') updatedAt = serializers.SerializerMethodField(method_name='get_updated_at') included_serializers = { 'file': 'scholar.apps.papers.serializers.FileSerializer', 'author': 'scholar.apps.profiles.serializers.ProfileSerializer', 'tags': 'scholar.apps.posts.serializers.TagSerializer', 'comments': 'scholar.apps.posts.serializers.CommentSerializer', } @staticmethod def setup_eager_loading(queryset): queryset = queryset.select_related('author') return queryset def get_created_at(self, instance): return instance.created_at.isoformat() def get_updated_at(self, instance): return instance.updated_at.isoformat() def get_favorited(self, instance): request = self.context.get('request', None) if request is None: return False if not request.user.is_authenticated(): return None return request.user.profile.is_favoriting(instance) def get_favorites_count(self, instance): return instance.favorited_by.count() def create(self, validated_data): profile = self.context['request'].user.profile file_pk = self.context['file_pk'] if file_pk: try: file = File.objects.get(pk=file_pk) except File.DoesNotExist: raise NotFound('File Not Found') tags = validated_data.pop('tags', []) annotation = Annotation.objects.create( **validated_data, author=profile, file=file, ) for tag in tags: annotation.tags.add(tag) return annotation class JSONAPIMeta: included_resources = ['author'] class Meta: model = Annotation fields = ( 'id', 'public', 'file', 'selectors', 'comment', 'color', 'author', 'tags', 'favorited', 'favoritesCount', 'comments', 'createdAt', 'updatedAt', )