Reputation: 1372
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
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
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
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