Django休息框架:serializers.ReadOnlyField()在可浏览的api中不显示字段 [英] Django rest framework: serializers.ReadOnlyField() doesn't display field in browsable api

查看:2214
本文介绍了Django休息框架:serializers.ReadOnlyField()在可浏览的api中不显示字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



我了解用户删除表单输入上的禁用属性的安全性问题(尽管我很惊讶django不在本机处理),那么如何在结果中的api.html模板中实现一个只读字段?



serializers.py

 类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框架,所以任何帮助将不胜感激!

解决方案

您有两个选项:


  1. 要计算模型中的结果


  2. 或将字段添加到序列化


您选择的是取决于您是否要在其他地方使用计算结果,以及是否可以触摸模型。



当您想在模型中计算结果



按照Django的派生全名,例如:



如果要在窗体



上显示只读字段,则需要覆盖restframework模板。 / p>


  • 确保您的模板在restframework之前加载(即您的应用程序位于settings.py中的restframework之上)

  • 使用您应用下的模板目录

  • 在模板中创建子目录dir:restframework / horizo​​ntal

  • 复制表单.html和input.html从Python的Lib\site-packages\rest_framework\\模板\rest_framework\horizo​​ntal\


  • 更改form.html





  {%load rest_framework%} 
{%表单中的字段%}
{%render_field字段样式=样式%}
{%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%}> 




结果:




Django rest framework: How can I display a read-only field in the browsable api?

When I add result = serializers.CharField(read_only=True) to my model serializer, the form no longer renders the results field.

I understand the security concerns of a user removing the disabled attribute on a form input (though I am surprised django doesn't handle this natively), so how can I implement a read-only field in the api.html template from result?

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')

I am new to the django-rest framework, so any help would be appreciated!

解决方案

You have 2 options:

  1. either to calculate the result in the model

  2. or to add the field within the serialization

What you choose depends on whether you want to use that calculated result also somewhere else and whether you can touch models.

When you want to calculate the result in the model

Follow the example of Django's derived fullname, somewhere around: https://github.com/django/django/blob/master/django/contrib/auth/models.py#L348

Or explained here in the doc: https://docs.djangoproject.com/en/dev/topics/db/models/#model-methods

That will act as a read only field for DRF automatically.

You can see the usage in the code bellow (get_full_name).

When you want to add field within serialization

You have the answer in the DRF docs: http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

SerializerMethodField This is a read-only field...It can be used to add any sort of data to the serialized representation of your object.

Example hours_since_joined in serializers.py:

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')

For your case:

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"

To show the added fields in the DRF's browsable API

You need to list them in the Meta's fields - see example above. That will present that in the browsable output on requests. However it will not show them in the DRF's HTML form. The reason is that the HTML form is used for submitting information only, so the restframework template skips the read only field in rendering.

As you can see the full name and hours since joined is not rendered in the form, but is available for API:

If you want to show read only fields also on the form

you need to override the restframework templates.

  • make sure your templates are loaded before the restframework's (i.e. your app is above the restframework in the settings.py)
  • use the templates dir under your app
  • create subdir in your templates dir: restframework/horizontal
  • copy the form.html and input.html from Python's Lib\site-packages\rest_framework\templates\rest_framework\horizontal\

  • change the form.html

{% load rest_framework %}
{% for field in form %}
    {% render_field field style=style %}
{% endfor %}

  • change input line in the input.html (adding disabled attribute)

    <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 %}>
    

The result:

这篇关于Django休息框架:serializers.ReadOnlyField()在可浏览的api中不显示字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆