Django休息框架:serializers.ReadOnlyField()在可浏览的api中不显示字段 [英] Django rest framework: serializers.ReadOnlyField() doesn't display field in browsable 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框架,所以任何帮助将不胜感激!
您有两个选项:
-
要计算模型中的结果
-
或将字段添加到序列化
您选择的是取决于您是否要在其他地方使用计算结果,以及是否可以触摸模型。
当您想在模型中计算结果
按照Django的派生全名,例如:
如果要在窗体
上显示只读字段,则需要覆盖restframework模板。 / p>
- 确保您的模板在restframework之前加载(即您的应用程序位于settings.py中的restframework之上)
- 使用您应用下的模板目录
- 在模板中创建子目录dir:restframework / horizontal
-
复制表单.html和input.html从Python的Lib\site-packages\rest_framework\\模板\rest_framework\horizontal\
-
更改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:
either to calculate the result in the model
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屋!