示例#1
0
    def one_member(self):
        return

    @property
    def many_members(self):
        return


@pytest.mark.parametrize(
    'serializer_field,expect_array', (
        (relations.SerializerMethodResourceRelatedField(model=MemberWithCustomID, source='get_member', read_only=True),
         False),
        (relations.SerializerMethodResourceRelatedField(model=MemberWithCustomID, source='get_members', read_only=True,
                                                        many=True),
         True),
        (relations.ResourceRelatedField(model=MemberWithCustomID, source='one_member', read_only=True),
         False),
        (relations.ResourceRelatedField(model=MemberWithCustomID, source='many_members', read_only=True, many=True),
         True),
        (relations.ResourceRelatedField(queryset=MemberWithCustomID.objects.all(), source='one_member'),
         False),
        (relations.ResourceRelatedField(queryset=MemberWithCustomID.objects.all(), source='many_members', many=True),
         True),
    )
)
def test_get__manual_related_resource(serializer_field, expect_array):
    """
    Support off combinations of related resources fields – they do supply models or don't.
    """
    class ProjectSerializer(serializers.ModelSerializer):
        member_relation = serializer_field
示例#2
0
class AbsenceBalanceSerializer(Serializer):
    credit = SerializerMethodField()
    used_days = SerializerMethodField()
    used_duration = SerializerMethodField()
    balance = SerializerMethodField()

    user = relations.ResourceRelatedField(model=get_user_model(),
                                          read_only=True)

    absence_type = relations.ResourceRelatedField(model=models.AbsenceType,
                                                  read_only=True,
                                                  source="id")

    absence_credits = relations.SerializerMethodResourceRelatedField(
        source="get_absence_credits",
        model=models.AbsenceCredit,
        many=True,
        read_only=True,
    )

    def _get_start(self, instance):
        return date(instance.date.year, 1, 1)

    def get_credit(self, instance):
        """
        Calculate how many days are approved for given absence type.

        For absence types which fill worktime this will be None.
        """
        if "credit" in instance:
            return instance["credit"]

        # id is mapped to absence type
        absence_type = instance.id

        start = self._get_start(instance)

        # avoid multiple calculations as get_balance needs it as well
        instance["credit"] = absence_type.calculate_credit(
            instance.user, start, instance.date)
        return instance["credit"]

    def get_used_days(self, instance):
        """
        Calculate how many days are used of given absence type.

        For absence types which fill worktime this will be None.
        """
        if "used_days" in instance:
            return instance["used_days"]

        # id is mapped to absence type
        absence_type = instance.id

        start = self._get_start(instance)

        # avoid multiple calculations as get_balance needs it as well
        instance["used_days"] = absence_type.calculate_used_days(
            instance.user, start, instance.date)
        return instance["used_days"]

    def get_used_duration(self, instance):
        """
        Calculate duration of absence type.

        For absence types which fill worktime this will be None.
        """
        # id is mapped to absence type
        absence_type = instance.id
        if not absence_type.fill_worktime:
            return None

        start = self._get_start(instance)
        absences = sum(
            [
                absence.calculate_duration(
                    models.Employment.objects.get_at(instance.user,
                                                     absence.date))
                for absence in Absence.objects.filter(
                    user=instance.user,
                    date__range=[start, instance.date],
                    type_id=instance.id,
                ).select_related("type")
            ],
            timedelta(),
        )
        return duration_string(absences)

    def get_absence_credits(self, instance):
        """Get the absence credits for the user and type."""
        if "absence_credits" in instance:
            return instance["absence_credits"]

        # id is mapped to absence type
        absence_type = instance.id

        start = self._get_start(instance)
        absence_credits = models.AbsenceCredit.objects.filter(
            absence_type=absence_type,
            user=instance.user,
            date__range=[start, instance.date],
        ).select_related("user")

        # avoid multiple calculations when absence credits need to be included
        instance["absence_credits"] = absence_credits

        return absence_credits

    def get_balance(self, instance):
        # id is mapped to absence type
        absence_type = instance.id
        if absence_type.fill_worktime:
            return None

        return self.get_credit(instance) - self.get_used_days(instance)

    included_serializers = {
        "absence_type": "timed.employment.serializers.AbsenceTypeSerializer",
        "absence_credits":
        "timed.employment.serializers.AbsenceCreditSerializer",
    }

    class Meta:
        resource_name = "absence-balances"
示例#3
0
class EntrySerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        super(EntrySerializer, self).__init__(*args, **kwargs)
        # to make testing more concise we'll only output the
        # `featured` field when it's requested via `include`
        request = kwargs.get("context", {}).get("request")
        if request and "featured" not in request.query_params.get(
                "include", []):
            self.fields.pop("featured", None)

    included_serializers = {
        "authors": "example.serializers.AuthorSerializer",
        "comments": "example.serializers.CommentSerializer",
        "featured": "example.serializers.EntrySerializer",
        "suggested": "example.serializers.EntrySerializer",
        "tags": "example.serializers.TaggedItemSerializer",
    }

    body_format = serializers.SerializerMethodField()
    # single related from model
    blog_hyperlinked = relations.HyperlinkedRelatedField(
        related_link_view_name="entry-blog",
        related_link_url_kwarg="entry_pk",
        self_link_view_name="entry-relationships",
        read_only=True,
        source="blog",
    )
    # many related from model
    comments = relations.ResourceRelatedField(many=True, read_only=True)
    # many related hyperlinked from model
    comments_hyperlinked = relations.HyperlinkedRelatedField(
        related_link_view_name="entry-comments",
        related_link_url_kwarg="entry_pk",
        self_link_view_name="entry-relationships",
        many=True,
        read_only=True,
        source="comments",
    )
    # many related from serializer
    suggested = relations.SerializerMethodResourceRelatedField(
        related_link_view_name="entry-suggested",
        related_link_url_kwarg="entry_pk",
        self_link_view_name="entry-relationships",
        model=Entry,
        many=True,
    )
    # many related hyperlinked from serializer
    suggested_hyperlinked = relations.SerializerMethodHyperlinkedRelatedField(
        related_link_view_name="entry-suggested",
        related_link_url_kwarg="entry_pk",
        self_link_view_name="entry-relationships",
        model=Entry,
        many=True,
    )
    # single related from serializer
    featured = relations.SerializerMethodResourceRelatedField(model=Entry)
    # single related hyperlinked from serializer
    featured_hyperlinked = relations.SerializerMethodHyperlinkedRelatedField(
        related_link_view_name="entry-featured",
        related_link_url_kwarg="entry_pk",
        self_link_view_name="entry-relationships",
        model=Entry,
        read_only=True,
    )
    tags = relations.ResourceRelatedField(many=True, read_only=True)

    def get_suggested(self, obj):
        return Entry.objects.exclude(pk=obj.pk)

    def get_featured(self, obj):
        return Entry.objects.exclude(pk=obj.pk).first()

    def get_body_format(self, obj):
        return "text"

    class Meta:
        model = Entry
        fields = (
            "blog",
            "blog_hyperlinked",
            "headline",
            "body_text",
            "pub_date",
            "mod_date",
            "authors",
            "comments",
            "comments_hyperlinked",
            "featured",
            "suggested",
            "suggested_hyperlinked",
            "tags",
            "featured_hyperlinked",
        )
        read_only_fields = ("tags", )
        meta_fields = ("body_format", )

    class JSONAPIMeta:
        included_resources = ["comments"]
示例#4
0
class EntrySerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        super(EntrySerializer, self).__init__(*args, **kwargs)
        # to make testing more concise we'll only output the
        # `featured` field when it's requested via `include`
        request = kwargs.get('context', {}).get('request')
        if request and 'featured' not in request.query_params.get(
                'include', []):
            self.fields.pop('featured', None)

    included_serializers = {
        'authors': 'example.serializers.AuthorSerializer',
        'comments': 'example.serializers.CommentSerializer',
        'featured': 'example.serializers.EntrySerializer',
        'suggested': 'example.serializers.EntrySerializer',
        'tags': 'example.serializers.TaggedItemSerializer',
    }

    body_format = serializers.SerializerMethodField()
    # single related from model
    blog_hyperlinked = relations.HyperlinkedRelatedField(
        related_link_view_name='entry-blog',
        related_link_url_kwarg='entry_pk',
        self_link_view_name='entry-relationships',
        read_only=True,
        source='blog')
    # many related from model
    comments = relations.ResourceRelatedField(many=True, read_only=True)
    # many related hyperlinked from model
    comments_hyperlinked = relations.HyperlinkedRelatedField(
        related_link_view_name='entry-comments',
        related_link_url_kwarg='entry_pk',
        self_link_view_name='entry-relationships',
        many=True,
        read_only=True,
        source='comments')
    # many related from serializer
    suggested = relations.SerializerMethodResourceRelatedField(
        related_link_view_name='entry-suggested',
        related_link_url_kwarg='entry_pk',
        self_link_view_name='entry-relationships',
        source='get_suggested',
        model=Entry,
        many=True,
        read_only=True)
    # many related hyperlinked from serializer
    suggested_hyperlinked = relations.SerializerMethodHyperlinkedRelatedField(
        related_link_view_name='entry-suggested',
        related_link_url_kwarg='entry_pk',
        self_link_view_name='entry-relationships',
        source='get_suggested',
        model=Entry,
        many=True,
        read_only=True)
    # single related from serializer
    featured = relations.SerializerMethodResourceRelatedField(
        source='get_featured', model=Entry, read_only=True)
    # single related hyperlinked from serializer
    featured_hyperlinked = relations.SerializerMethodHyperlinkedRelatedField(
        related_link_view_name='entry-featured',
        related_link_url_kwarg='entry_pk',
        self_link_view_name='entry-relationships',
        source='get_featured',
        model=Entry,
        read_only=True)
    tags = TaggedItemSerializer(many=True, read_only=True)

    def get_suggested(self, obj):
        return Entry.objects.exclude(pk=obj.pk)

    def get_featured(self, obj):
        return Entry.objects.exclude(pk=obj.pk).first()

    def get_body_format(self, obj):
        return 'text'

    class Meta:
        model = Entry
        fields = ('blog', 'blog_hyperlinked', 'headline', 'body_text',
                  'pub_date', 'mod_date', 'authors', 'comments',
                  'comments_hyperlinked', 'featured', 'suggested',
                  'suggested_hyperlinked', 'tags', 'featured_hyperlinked')
        read_only_fields = ('tags', )
        meta_fields = ('body_format', )

    class JSONAPIMeta:
        included_resources = ['comments']
示例#5
0
class UserSerializer(ModelSerializer):
    """User serializer."""

    employments = relations.ResourceRelatedField(many=True, read_only=True)
    worktime_balance = SerializerMethodField()
    user_absence_types = relations.SerializerMethodResourceRelatedField(
        source='get_user_absence_types',
        model=models.UserAbsenceType,
        many=True,
        read_only=True)

    def get_user_absence_types(self, instance):
        """Get the user absence types for this user.

        :returns: All absence types for this user
        """
        request = self.context.get('request')

        end = datetime.strptime(
            request.query_params.get('until',
                                     date.today().strftime('%Y-%m-%d')),
            '%Y-%m-%d').date()

        try:
            employment = models.Employment.objects.for_user(instance, end)
        except models.Employment.DoesNotExist:
            return models.UserAbsenceType.objects.none()

        start = max(employment.start_date, date(date.today().year, 1, 1))

        return models.UserAbsenceType.objects.with_user(instance, start, end)

    def get_worktime(self, user, start=None, end=None):
        """Calculate the reported, expected and balance for user.

        1.  Determine the current employment of the user
        2.  Take the latest of those two as start date:
             * The start of the year
             * The start of the current employment
        3.  Take the delivered date if given or the current date as end date
        4.  Determine the count of workdays within start and end date
        5.  Determine the count of public holidays within start and end date
        6.  The expected worktime consists of following elements:
             * Workdays
             * Subtracted by holidays
             * Multiplicated with the worktime per day of the employment
        7.  Determine the overtime credit duration within start and end date
        8.  The reported worktime is the sum of the durations of all reports
            for this user within start and end date
        9.  The absences are all absences for this user between the start and
            end time
        10. The balance is the reported time plus the absences plus the
            overtime credit minus the expected worktime

        :param user:       user to get worktime from
        :param start_date: worktime starting on  given day;
                           if not set when employment started resp. begining of
                           the year
        :param end_date:   worktime till day or if not set today
        :returns: tuple of 3 values reported, expected and balance in given
                  time frame
        """
        end = end or date.today()

        try:
            employment = models.Employment.objects.for_user(user, end)
        except models.Employment.DoesNotExist:
            # If there is no active employment, set the balance to 0
            return timedelta(), timedelta(), timedelta()

        location = employment.location

        if start is None:
            start = max(employment.start_date, date(date.today().year, 1, 1))

        # workdays is in isoweekday, byweekday expects Monday to be zero
        week_workdays = [int(day) - 1 for day in employment.location.workdays]
        workdays = rrule.rrule(rrule.DAILY,
                               dtstart=start,
                               until=end,
                               byweekday=week_workdays).count()

        # converting workdays as db expects 1 (Sunday) to 7 (Saturday)
        workdays_db = [
            # special case for Sunday
            int(day) == 7 and 1 or int(day) + 1 for day in location.workdays
        ]
        holidays = models.PublicHoliday.objects.filter(
            location=location,
            date__gte=start,
            date__lte=end,
            date__week_day__in=workdays_db).count()

        expected_worktime = employment.worktime_per_day * (workdays - holidays)

        overtime_credit = sum(
            models.OvertimeCredit.objects.filter(user=user,
                                                 date__gte=start,
                                                 date__lte=end).values_list(
                                                     'duration', flat=True),
            timedelta())

        reported_worktime = sum(
            Report.objects.filter(user=user, date__gte=start,
                                  date__lte=end).values_list('duration',
                                                             flat=True),
            timedelta())

        absences = sum(
            Absence.objects.filter(user=user, date__gte=start,
                                   date__lte=end).values_list('duration',
                                                              flat=True),
            timedelta())

        reported = reported_worktime + absences + overtime_credit

        return (reported, expected_worktime, reported - expected_worktime)

    def get_worktime_balance(self, instance):
        """Format the worktime balance.

        :return: The formatted worktime balance.
        :rtype:  str
        """
        request = self.context.get('request')
        until = request.query_params.get('until')
        end_date = until and datetime.strptime(until, '%Y-%m-%d').date()

        _, _, balance = self.get_worktime(instance, None, end_date)
        return duration_string(balance)

    included_serializers = {
        'employments':
        'timed.employment.serializers.EmploymentSerializer',
        'user_absence_types':
        'timed.employment.serializers.UserAbsenceTypeSerializer'
    }

    class Meta:
        """Meta information for the user serializer."""

        model = get_user_model()
        fields = [
            'username',
            'first_name',
            'last_name',
            'email',
            'employments',
            'worktime_balance',
            'is_staff',
            'is_active',
            'user_absence_types',
        ]
示例#6
0
class AuthorSerializer(serializers.ModelSerializer):
    bio = relations.ResourceRelatedField(
        related_link_view_name="author-related",
        self_link_view_name="author-relationships",
        queryset=AuthorBio.objects,
    )
    entries = relations.ResourceRelatedField(
        related_link_view_name="author-related",
        self_link_view_name="author-relationships",
        queryset=Entry.objects,
        many=True,
    )
    first_entry = relations.SerializerMethodResourceRelatedField(
        related_link_view_name="author-related",
        self_link_view_name="author-relationships",
        model=Entry,
    )
    comments = relations.HyperlinkedRelatedField(
        related_link_view_name="author-related",
        self_link_view_name="author-relationships",
        queryset=Comment.objects,
        many=True,
    )
    secrets = serializers.HiddenField(default="Shhhh!")
    defaults = serializers.CharField(
        default="default",
        max_length=20,
        min_length=3,
        write_only=True,
        help_text="help for defaults",
    )
    initials = serializers.SerializerMethodField()
    included_serializers = {
        "bio": AuthorBioSerializer,
        "type": AuthorTypeSerializer
    }
    related_serializers = {
        "bio": "example.serializers.AuthorBioSerializer",
        "type": "example.serializers.AuthorTypeSerializer",
        "comments": "example.serializers.CommentSerializer",
        "entries": "example.serializers.EntrySerializer",
        "first_entry": "example.serializers.EntrySerializer",
    }

    class Meta:
        model = Author
        fields = (
            "name",
            "email",
            "bio",
            "entries",
            "comments",
            "first_entry",
            "type",
            "secrets",
            "defaults",
            "initials",
        )
        meta_fields = ("initials", )

    def get_first_entry(self, obj):
        return obj.entries.first()

    def get_initials(self, obj):
        return "".join([word[0] for word in obj.name.split(" ")])
示例#7
0
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',
        )
示例#8
0
class ProfileSerializer(serializers.ModelSerializer):
    username = serializers.CharField(source='user.username')
    bio = serializers.CharField(allow_blank=True, required=False)
    image = serializers.SerializerMethodField()
    following = serializers.SerializerMethodField()

    # followings = relations.ResourceRelatedField(many=True, read_only=True)
    # followers = relations.ResourceRelatedField(many=True, read_only=True)
    collects = relations.ResourceRelatedField(many=True, read_only=True)
    favorites = relations.ResourceRelatedField(many=True, read_only=True)
    owns = relations.ResourceRelatedField(many=True, read_only=True)

    followings = relations.SerializerMethodResourceRelatedField(
        source='get_followings',
        read_only=True,
        model=Profile,
    )
    followers = relations.SerializerMethodResourceRelatedField(
        source='get_followers',
        read_only=True,
        model=Profile,
    )

    related_serializers = {
        'followings': 'scholar.apps.profiles.serializers.ProfileSerializer',
        'followers': 'scholar.apps.profiles.serializers.ProfileSerializer',
        'collects': 'scholar.apps.posts.serializers.PostSerializer',
        'favorites':
        'scholar.apps.annotations.serializers.annotationSerializer',
        'owns': 'scholar.apps.papers.serializers.FileSerializer',
    }

    class Meta:
        model = Profile
        fields = (
            'user',
            'username',
            'bio',
            'image',
            'following',
            'followers',
            'followings',
            'collects',
            'favorites',
            'owns',
        )
        read_only_fields = (
            'user',
            'username',
            'collects',
            'favorites',
            'owns',
            'followers',
            'followings',
        )

    def get_image(self, obj):
        if obj.image:
            return obj.image
        return 'https://static.productionready.io/images/smiley-cyrus.jpg'

    def get_following(self, instance):
        request = self.context.get('request', None)
        if request is None:
            return False
        if not request.user.is_authenticated():
            return False

        follower = request.user.profile
        followee = instance
        return follower.is_following(followee)

    def get_followings(self, instance):
        return instance.follows.all()

    def get_followers(self, instance):
        return instance.followed_by.all()
class OrganizationSerializer(serializers.HyperlinkedModelSerializer):

    parent = relations.ResourceRelatedField(
        queryset=Organization.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='organization-related',
        related_link_url_kwarg='pk',
        self_link_view_name='organization-relationships',
    )

    children = relations.ResourceRelatedField(
        queryset=Organization.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='organization-related',
        related_link_url_kwarg='pk',
        self_link_view_name='organization-relationships',
    )

    publishers = relations.ResourceRelatedField(
        queryset=Publisher.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='organization-related',
        related_link_url_kwarg='pk',
        self_link_view_name='organization-relationships',
    )

    included_serializers = {
        'parent': 'resolver.serializers.OrganizationSerializer',
        'children': 'resolver.serializers.OrganizationSerializer',
        'publishers': 'resolver.serializers.PublisherSerializer',
    }

    class Meta:
        model = Organization
        fields = ('url', 'parent', 'children', 'name', 'abbreviation',
                  'category', 'href', 'publishers', 'added', 'modified')
        read_only_fields = ('added', 'modified')
        meta_fields = ('added', 'modified')

    def create(self, validated_data: Dict):
        children = validated_data.pop('children', None)
        publishers = validated_data.pop('publishers', None)

        self.is_valid(raise_exception=True)

        try:
            organization = Organization.objects.get(**validated_data)
        except Organization.DoesNotExist:
            organization = Organization.create(**validated_data)
            try:
                organization.save()
            except IntegrityError as e:
                raise ResourceExistsError(
                    "organization resource already exists", code=409)
            if children:
                organization.children.add(*children, bulk=True)
            if publishers:
                organization.publishers.add(*publishers, bulk=True)
        return organization

    def update(self, instance: Organization, validated_data: Dict):
        if 'name' in validated_data or 'parent' in validated_data:
            raise IntegrityError(
                "fields 'name' and 'parent' are immutable for the organizations resource"
            )

        children = validated_data.pop('children', None)
        publishers = validated_data.pop('publishers', None)

        instance.abbreviation = validated_data.get('abbreviation',
                                                   instance.abbreviation)
        instance.category = validated_data.get('category', instance.category)
        instance.href = validated_data.get('href', instance.href)

        instance.save()

        if children:
            instance.children.bulk_update(children, bulk=True, clear=True)
        else:
            instance.children.clear(bulk=True)
        if publishers:
            instance.publishers.bulk_update(publishers, bulk=True, clear=True)
        else:
            instance.publishers.clear(bulk=True)

        return instance
示例#10
0
class MediaTypeSerializer(serializers.HyperlinkedModelSerializer):

    accepting_endpoints = relations.ResourceRelatedField(
        queryset=EndPoint.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='mediatype-related',
        related_link_url_kwarg='pk',
        self_link_view_name='mediatype-relationships',
    )

    delivering_endpoints = relations.ResourceRelatedField(
        queryset=EndPoint.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='mediatype-related',
        related_link_url_kwarg='pk',
        self_link_view_name='mediatype-relationships',
    )

    included_serializers = {
        'accepting_endpoints': 'resolver.serializers.EndPointSerializer',
        'delivering_endpoints': 'resolver.serializers.EndPointSerializer',
    }

    class Meta:
        model = MediaType
        fields = ('url', 'name', 'description', 'accepting_endpoints',
                  'delivering_endpoints', 'added', 'modified')
        read_only_fields = ('added', 'modified')
        meta_fields = ('added', 'modified')

    def create(self, validated_data: Dict):
        accepting_endpoints = validated_data.pop('accepting_endpoints', None)
        delivering_endpoints = validated_data.pop('delivering_endpoints', None)

        self.is_valid(raise_exception=True)

        try:
            mediatype = MediaType.objects.get(**validated_data)
        except MediaType.DoesNotExist:
            mediatype = MediaType.create(**validated_data)
            try:
                mediatype.save()
            except IntegrityError as e:
                raise ResourceExistsError("mediatype resource already exists",
                                          code=409)
            if accepting_endpoints:
                mediatype.accepting_endpoints.add(*accepting_endpoints,
                                                  bulk=True)
            if delivering_endpoints:
                mediatype.delivering_endpoints.add(*delivering_endpoints,
                                                   bulk=True)
        return mediatype

    def update(self, instance: MediaType, validated_data: Dict):
        if 'name' in validated_data:
            raise IntegrityError(
                "field 'name', is immutable for the mediatypes resource")

        accepting_endpoints = validated_data.pop('accepting_endpoints', None)
        delivering_endpoints = validated_data.pop('delivering_endpoints', None)

        instance.description = validated_data.get('description',
                                                  instance.description)

        instance.save()

        if accepting_endpoints:
            instance.accepting_endpoints.bulk_update(accepting_endpoints,
                                                     bulk=True,
                                                     clear=True)
        else:
            instance.accepting_endpoints.clear(bulk=True)
        if delivering_endpoints:
            instance.delivering_endpoints.bulk_update(delivering_endpoints,
                                                      bulk=True,
                                                      clear=True)
        else:
            instance.delivering_endpoints.clear(bulk=True)

        return instance
示例#11
0
class EndPointSerializer(serializers.HyperlinkedModelSerializer):

    accept_header_media_types = relations.ResourceRelatedField(
        queryset=MediaType.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='endpoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='endpoint-relationships',
    )

    content_media_types = relations.ResourceRelatedField(
        queryset=MediaType.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='endpoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='endpoint-relationships',
    )

    request_schema_endpoint = relations.ResourceRelatedField(
        queryset=MediaType.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='endpoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='endpoint-relationships',
    )

    response_schema_endpoint = relations.ResourceRelatedField(
        queryset=MediaType.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='endpoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='endpoint-relationships',
    )

    full_path_uri = serializers.CharField()

    included_serializers = {
        'entrypoint': 'resolver.serializers.EntryPointSerializer',
        'accept_header_media_types':
        'resolver.serializers.MediaTypeSerializer',
        'content_media_types': 'resolver.serializers.MediaTypeSerializer',
        'request_schema_endpoint': 'resolver.serializers.EndPointSerializer',
        'response_schema_endpoint': 'resolver.serializers.EndPointSerializer',
    }

    request_methods = MultipleChoiceField(choices=defaults.http_verbs,
                                          default=['GET'])

    class Meta:
        model = EndPoint
        fields = ('url', 'entrypoint', 'uri', 'full_path_uri', 'description',
                  'category', 'request_methods', 'accept_header_media_types',
                  'content_media_types', 'request_schema_endpoint',
                  'response_schema_endpoint', 'full_path_uri', 'added',
                  'modified')
        read_only_fields = ('full_path_uri', 'added', 'modified')
        meta_fields = ('added', 'modified')

    def create(self, validated_data: Dict):
        accept_header_mediatypes = validated_data.pop(
            'accept_header_mediatypes', None)
        content_mediatypes = validated_data.pop('content_mediatypes', None)
        request_schema_endpoint = validated_data.pop('request_schema_endpoint',
                                                     None)
        response_schema_endpoint = validated_data.pop(
            'response_schema_endpoint', None)

        self.is_valid(raise_exception=True)

        try:
            endpoint = EndPoint.objects.get(**validated_data)
        except EndPoint.DoesNotExist:
            endpoint = EndPoint.create(**validated_data)
            try:
                endpoint.save()
            except IntegrityError as e:
                raise ResourceExistsError("endpoint resource already exists",
                                          code=409)
            if accept_header_mediatypes:
                endpoint.accept_header_mediatypes.add(
                    *accept_header_mediatypes, bulk=True)
            if content_mediatypes:
                endpoint.content_mediatypes.add(*content_mediatypes, bulk=True)
            if request_schema_endpoint:
                endpoint.request_schema_endpoint.add(*request_schema_endpoint,
                                                     bulk=True)
            if response_schema_endpoint:
                endpoint.response_schema_endpoint.add(
                    *response_schema_endpoint, bulk=True)
        return endpoint

    def update(self, instance: EndPoint, validated_data: Dict):
        if 'entrypoint' in validated_data or 'uri' in validated_data:
            raise IntegrityError(
                "fields 'entrypoint', and 'uri' are immutable \
            for the endpoints resource")

        accept_header_media_types = validated_data.pop(
            'accept_header_mediatypes', None)
        content_media_types = validated_data.pop('content_mediatypes', None)
        request_schema_endpoint = validated_data.pop('request_schema_endpoint',
                                                     None)
        response_schema_endpoint = validated_data.pop(
            'response_schema_endpoint', None)

        instance.category = validated_data.get('category', instance.category)
        instance.request_methods = validated_data.get('request_methods',
                                                      instance.request_methods)
        instance.description = validated_data.get('description',
                                                  instance.description)
        instance.save()

        if accept_header_media_types:
            instance.accept_header_media_types.bulk_update(
                accept_header_media_types, bulk=True, clear=True)
        else:
            instance.accept_header_media_types.clear(bulk=True)

        if content_media_types:
            instance.content_media_types.bulk_update(content_media_types,
                                                     bulk=True,
                                                     clear=True)
        else:
            instance.content_media_types.clear(bulk=True)

        if request_schema_endpoint:
            instance.request_schema_endpoint.bulk_update(
                request_schema_endpoint, bulk=True, clear=True)
        else:
            instance.request_schema_endpoint.clear(bulk=True)

        if content_media_types:
            instance.response_schema_endpoint.bulk_update(
                response_schema_endpoint, bulk=True, clear=True)
        else:
            instance.response_schema_endpoint.clear(bulk=True)

        return instance
示例#12
0
class EntryPointSerializer(serializers.HyperlinkedModelSerializer):

    parent = relations.ResourceRelatedField(
        queryset=EntryPoint.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='entrypoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='entrypoint-relationships',
    )

    publisher = relations.ResourceRelatedField(
        queryset=Publisher.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='entrypoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='entrypoint-relationships',
    )

    children = relations.ResourceRelatedField(
        queryset=EntryPoint.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='entrypoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='entrypoint-relationships',
    )

    endpoints = relations.ResourceRelatedField(
        queryset=EndPoint.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='entrypoint-related',
        related_link_url_kwarg='pk',
        self_link_view_name='entrypoint-relationships',
    )

    included_serializers = {
        'publisher': 'resolver.serializers.PublisherSerializer',
        'endpoints': 'resolver.serializers.EndPointSerializer',
        'parent': 'resolver.serializers.EntryPointSerializer',
        'children': 'resolver.serializers.EntryPointSerializer',
    }

    class Meta:
        model = EntryPoint
        fields = ('url', 'parent', 'children', 'publisher', 'name',
                  'description', 'category', 'href', 'entrypoint_href',
                  'endpoints', 'added', 'modified')
        read_only_fields = ('added', 'modified')
        meta_fields = ('added', 'modified')

    def create(self, validated_data: Dict):
        children = validated_data.pop('children', None)
        publishers = validated_data.pop('publishers', None)
        endpoints = validated_data.pop('endpoints', None)

        self.is_valid(raise_exception=True)

        try:
            entrypoint = EntryPoint.objects.get(**validated_data)
        except EntryPoint.DoesNotExist:
            entrypoint = EntryPoint.create(**validated_data)
            try:
                entrypoint.save()
            except IntegrityError as e:
                raise ResourceExistsError("entrypoint resource already exists",
                                          code=409)
            if children:
                entrypoint.children.add(*children, bulk=True)
            if publishers:
                entrypoint.publishers.add(*publishers, bulk=True)
            if endpoints:
                entrypoint.endpoints.add(*endpoints, bulk=True)

        return entrypoint

    def update(self, instance: EntryPoint, validated_data: Dict):
        if 'parent' in validated_data \
                or 'publisher' in validated_data \
                or 'href' in validated_data:
            raise IntegrityError(
                "fields 'parent', 'publisher', 'href' are immutable \
            for the entrypoints resource")

        children = validated_data.pop('children', None)
        endpoints = validated_data.pop('endpoints', None)

        instance.publisher = validated_data.get('publisher',
                                                instance.publisher)
        instance.entrypoint_href = validated_data.get('entrypoint_href',
                                                      instance.entrypoint_href)
        instance.name = validated_data.get('name', instance.name)
        instance.description = validated_data.get('description',
                                                  instance.description)
        instance.category = validated_data.get('category', instance.category)

        instance.save()

        if children:
            instance.children.bulk_update(children, bulk=True, clear=True)
        else:
            instance.children.clear(bulk=True)
        if endpoints:
            instance.children.bulk_update(endpoints, bulk=True, clear=True)
        else:
            instance.endpoints.clear(bulk=True)

        return instance
示例#13
0
class PublisherSerializer(serializers.HyperlinkedModelSerializer):

    parent = relations.ResourceRelatedField(
        queryset=Publisher.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='publisher-related',
        related_link_url_kwarg='pk',
        self_link_view_name='publisher-relationships',
    )

    organization = relations.ResourceRelatedField(
        queryset=Organization.objects,
        many=False,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='publisher-related',
        related_link_url_kwarg='pk',
        self_link_view_name='publisher-relationships',
    )

    children = relations.ResourceRelatedField(
        queryset=Publisher.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='publisher-related',
        related_link_url_kwarg='pk',
        self_link_view_name='publisher-relationships',
    )

    entrypoints = relations.ResourceRelatedField(
        queryset=EntryPoint.objects,
        many=True,
        read_only=False,
        required=False,
        default=None,
        related_link_view_name='publisher-related',
        related_link_url_kwarg='pk',
        self_link_view_name='publisher-relationships',
    )

    included_serializers = {
        'organization': 'resolver.serializers.OrganizationSerializer',
        'entrypoints': 'resolver.serializers.EntryPointSerializer',
        'parent': 'resolver.serializers.PublisherSerializer',
        'children': 'resolver.serializers.PublisherSerializer',
    }

    class Meta:
        model = Publisher
        fields = ('url', 'parent', 'children', 'organization', 'entrypoints',
                  'name', 'category', 'email', 'address', 'href', 'orcid',
                  'added', 'modified')
        read_only_fields = ('added', 'modified')
        meta_fields = ('added', 'modified')

    def create(self, validated_data: Dict):
        children = validated_data.pop('children', None)
        entrypoints = validated_data.pop('entrypoints', None)

        self.is_valid(raise_exception=True)

        try:
            publisher = Publisher.objects.get(**validated_data)
        except Publisher.DoesNotExist:
            publisher = Publisher.create(**validated_data)
            try:
                publisher.save()
            except IntegrityError as e:
                raise ResourceExistsError(
                    "organization resource already exists", code=409)
            if children:
                publisher.children.add(*children, bulk=True)
            if entrypoints:
                publisher.entrypoints.add(*entrypoints, bulk=True)
        return publisher

    def update(self, instance: Publisher, validated_data: Dict):
        if 'organization' in validated_data or 'parent' in validated_data or 'name' in validated_data:
            raise IntegrityError(
                "fields 'organization', 'parent', and 'name' are immutable for the publishers resource"
            )

        children = validated_data.pop('children', None)
        entrypoints = validated_data.pop('entrypoints', None)

        instance.category = validated_data.get('category', instance.category)
        instance.name = validated_data.get('name', instance.name)
        instance.email = validated_data.get('email', instance.email)
        instance.address = validated_data.get('address', instance.address)
        instance.href = validated_data.get('href', instance.href)
        instance.orcid = validated_data.get('orcid', instance.orcid)

        instance.save()

        if children:
            instance.children.bulk_update(children, bulk=True, clear=True)
        else:
            instance.children.clear(bulk=True)
        if entrypoints:
            instance.entrypoints.bulk_update(entrypoints,
                                             bulk=True,
                                             clear=True)
        else:
            instance.entrypoints.clear(bulk=True)

        return instance