django-rest-framework-bulk icon indicating copy to clipboard operation
django-rest-framework-bulk copied to clipboard

Limit the number of resources bulky created

Open JocelynDelalande opened this issue 10 years ago • 2 comments

Maybe it's not a feature in DRF-bulk but rather some code around that lib user writes. Just thinking about it, what do you think ?

JocelynDelalande avatar Jun 16 '15 11:06 JocelynDelalande

I like the idea and sound like it belongs here. I'll take a look when I can. Thanks

On Tue, Jun 16, 2015, 7:07 AM JocelynDelalande [email protected] wrote:

Maybe it's not a feature in DRF-bulk but rather some code around that lib user writes. Just thinking about it, what do you think ?

— Reply to this email directly or view it on GitHub https://github.com/miki725/django-rest-framework-bulk/issues/36.

miki725 avatar Jun 16 '15 11:06 miki725

@miki725 cool :)

Rationale here is that every API require limits, among others, to limit database load… and that DRF-bulk has no mechanism to set limits.

The limit must be enforced the sooner possible, to avoid putting stress on the API and then discarding request.

Here is how I do it currently, using serializers

A custom list serializer :

class SizeLimitedListSerializer(serializers.ListSerializer):
    DEFAULT_MAX_ITEMS=10000

    def run_validation(self, data=empty):
        """
        Natural place for this validation to occur would be in self.validate()
        but it's not a safe option as we would validate *all* items *before*
        rejecting.

        Overloading run_validation allows to raise ValidationError earlier.
        """
        try:
            max_items = self.Meta.max_items()
        except AttributeError:
            max_items = self.DEFAULT_MAX_ITEMS

        items_count = len(data)

        if items_count > max_items:
            raise ValidationError(detail={'non_field_errors' : [
                    'Serializer limited to {} items at once, got {}'.format(
                        max_items, items_count)
                ]})
        return super().run_validation(data)

Optionaly refine limit in child class

class MailListSerializer(SizeLimitedListSerializer):
    class Meta:
        # make it lazy, otherwise, overrided settings value can be missed
        max_items = lambda: settings.MAX_BULK_EMAILS

And finally mention that class in the main serializer :

class MailSerializer(serializers.ModelSerializer)
    class Meta:
        list_serializer_class = MailListSerializer

JocelynDelalande avatar Jun 16 '15 15:06 JocelynDelalande