Tanzaho
Tanzaho

Reputation: 1372

Can I disable a field in the Rest Framework API browsing view

I am using Django Rest Framework to serialize a model in which I have a foreignkey.

models.py

class Article(models.Model):
    author = models.ForeignKey(Author, related_name='articles')
    ... other fields...

serializers.py

class ArticleSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Article

I want to get rid of the 'HTML form' at the bottom of the browsable API view since I get a list with all my articles and retrieving them from the DB takes ages (I have some 100K articles, and each time the html form is displayed, my server does 100K queries).

I have read the answer from How to disable admin-style browsable interface of django-rest-framework? and I am currently displaying the view in JSON. However, I like the html view and would like to find a way to avoid the html form available at the bottom.

I don't want to properly remove the field from the view (I need to use it), but just remove the database queries used to populate the form.

Any idea ?

Upvotes: 8

Views: 3335

Answers (3)

Alechan
Alechan

Reputation: 896

@maerteijn answer will disable all forms: POST, PUT, DELETE and OPTIONS.

If you still want to allow the awesome "OPTIONS" button, you can do something like this

class NoHTMLFormBrowsableAPIRenderer(BrowsableAPIRenderer):
    OPTIONS_METHOD = "OPTIONS"

    def get_rendered_html_form(self, data, view, method, request):
        if method == self.OPTIONS_METHOD:
            return super().get_rendered_html_form(data, view, method, request)
        else:
            """
            We don't want the HTML forms to be rendered because it can be
            really slow with large datasets
            """
            return ""

And modify settings.py in the same way

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'myapp.renderers.NoHTMLFormBrowsableAPIRenderer',
    )
}

Upvotes: 0

maerteijn
maerteijn

Reputation: 660

Making the field read-only also means you cannot modify it, which is probably not wanted in all cases.

Another solution is to override the BrowsableApiRenderer so it won't display the HTML form (which can be indeed really slow with a lot of data).

This is surprisingly easy, just override get_rendered_html_form:

from rest_framework.renderers import BrowsableAPIRenderer


class NoHTMLFormBrowsableAPIRenderer(BrowsableAPIRenderer):

    def get_rendered_html_form(self, *args, **kwargs):
        """
        We don't want the HTML forms to be rendered because it can be
        really slow with large datasets
        """
        return ""

then adjust your settings to use this renderer:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'myapp.renderers.NoHTMLFormBrowsableAPIRenderer',
    )
}

Upvotes: 6

Tanzaho
Tanzaho

Reputation: 1372

I answer my own question. I found in the documentation the solution to my problem. I had to use the read_only attribute.

serializers.py

class ArticleSerializer(serializers.HyperlinkedModelSerializer):
    author = serializers.RelatedField(read_only=True)
    class Meta:
        model = Article
        fields = ('author', ...other_fields)

Upvotes: 4

Related Questions