Django rest框架:serializers.ReadOnlyField()不显示可浏览api中的字段

时间:2015-12-30 10:29:19

标签: python django rest serialization django-rest-framework

Django休息框架:如何在可浏览的api中显示只读字段?

当我将result = serializers.CharField(read_only=True)添加到模型序列化程序时,表单不再呈现结果字段。

我理解用户删除表单输入上的disabled属性的安全问题(虽然我很惊讶django本身不处理这个),所以如何在api中实现只读字段来自result的.html模板?

serializers.py

class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
result = serializers.CharField(read_only=True)

class Meta:
    model = Snippet
    fields = ('title', 'code', 'owner', 'url', 'result')

我是django-rest框架的新手,所以任何帮助都会受到赞赏!

2 个答案:

答案 0 :(得分:5)

您有两个选择:

  1. 要么计算模型中的结果

  2. 或在序列化中添加字段

  3. 您选择的内容取决于您是否希望在其他地方使用该计算结果以及是否可以触摸模型。

    如果要在模型中计算结果

    按照Django派生的全名的例子,在某处: https://github.com/django/django/blob/master/django/contrib/auth/models.py#L348

    或者在文档中解释:https://docs.djangoproject.com/en/dev/topics/db/models/#model-methods

    这将自动充当DRF的只读字段。

    您可以在下面的代码中看到用法(get_full_name)。

    如果要在序列化中添加字段

    您在DRF文档中有答案:http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

    SerializerMethodField 这是一个只读字段...它可用于将任何类型的数据添加到对象的序列化表示中。

    serializers.py中的hours_since_joined示例:

    from django.contrib.auth.models import User, Group
    from rest_framework import serializers
    from django.utils.timezone import now
    
    class UserSerializer(serializers.HyperlinkedModelSerializer):
        hours_since_joined = serializers.SerializerMethodField()
        class Meta:
            model = User
            fields = ('url', 'username', 'email', 'groups', 'hours_since_joined', 'first_name', 'last_name', 'get_full_name' )
    
        def get_hours_since_joined(self, obj):
            return (now() - obj.date_joined).total_seconds() // 3600
    
    class GroupSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = Group
            fields = ('url', 'name', 'user_set')
    

    对于你的情况:

    class SnippetSerializer(serializers.HyperlinkedModelSerializer):
        owner = serializers.ReadOnlyField(source='owner.username')
        result = serializers.SerializerMethodField()
    
        class Meta:
            model = Snippet
            fields = ('title', 'code', 'owner', 'url', 'result')
    
        def get_result(self, obj):
            # code here to calculate the result
            # or return obj.calc_result() if you have that calculation in the model
            return "some result"
    

    显示DRF可浏览API中的添加字段

    您需要在Meta的字段中列出它们 - 请参阅上面的示例。这将在请求的可浏览输出中显示。但是它不会在DRF的HTML表单中显示它们。原因是HTML表单仅用于提交信息,因此restframework模板会在渲染时跳过只读字段。

    正如您所看到的,自加入后的全名和小时数未在表单中呈现,但可用于API:

    enter image description here

    如果您还希望在表单上显示只读字段

    您需要覆盖restframework模板。

    • 确保您的模板在restframework之前加载(即您的应用程序位于settings.py中的restframework之上)
    • 使用您应用下的模板目录
    • 在模板目录中创建subdir:restframework / horizo​​ntal
    • 从Python的Lib \ site-packages \ rest_framework \ templates \ rest_framework \ horizo​​ntal \

    • 复制form.html和input.html
    • 更改form.html

    {% load rest_framework %}
    {% for field in form %}
        {% render_field field style=style %}
    {% endfor %}
    
    • 更改input.html中的输入行(添加已禁用的属性)

      <input name="{{ field.name }}"  {% if field.read_only %}disabled{% endif %} {% if style.input_type != "file" %}class="form-control"{% endif %} type="{{ style.input_type }}" {% if style.placeholder %}placeholder="{{ style.placeholder }}"{% endif %} {% if field.value %}value="{{ field.value }}"{% endif %}>
      

    结果:

    enter image description here

答案 1 :(得分:0)

对于无法在Browsable API中显示的人,模板文件夹应命名为:rest_framework