我可以在Rest Framework API浏览视图中禁用某个字段

时间:2014-04-14 14:30:17

标签: django django-rest-framework

我正在使用Django Rest Framework来序列化我有外键的模型。

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

我想摆脱HTML表单'在浏览器API视图的底部,因为我得到一个包含所有文章的列表,并从数据库中检索它们需要很长时间(我有100K篇文章,每次显示html表单时,我的服务器执行100K查询)。

我已阅读How to disable admin-style browsable interface of django-rest-framework?的答案,我目前正在以JSON格式显示该视图。但是,我喜欢html视图,并希望找到一种方法来避免底层的html表单。

我不想从视图中正确删除该字段(我需要使用它),但只需删除用于填充表单的数据库查询。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

我回答我自己的问题。 我在documentation找到了问题的解决方案。我不得不使用 read_only 属性。

serializers.py

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

答案 1 :(得分:3)

将字段设为只读也意味着您无法对其进行修改,这在所有情况下都可能不需要。

另一个解决方案是覆盖BrowsableApiRenderer,因此它不会显示HTML表单(对于大量数据来说,这确实很慢)。

这非常容易,只需覆盖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 ""

然后调整您的设置以使用此渲染器:

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

答案 2 :(得分:0)

@maerteijn答案将禁用所有形式:POST,PUT,DELETE和OPTIONS。

如果您仍然希望允许使用“ OPTIONS”按钮,则可以执行以下操作

<div contenteditable="true" bind:innerHTML={value}></div>
<div>{value}</div>
<button on:click={handle}>Update trigger</button>

并以相同的方式修改settings.py

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 ""