DJango REST Framework 只读字段
Posted
技术标签:
【中文标题】DJango REST Framework 只读字段【英文标题】:DJango REST Framework Read Only field 【发布时间】:2017-08-29 12:36:13 【问题描述】:我有一个字段owner
,它是ForeignKey
到User
的模型。
此字段在创建时为 required
。但是以后不能改了。
如何制作字段Non-Editable
?除了创建多个序列化器还有其他方法吗?
车库模型
class GarageDetails(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, )
name = models.CharField(_('Garage Name'), max_length=254, blank=False, null=False, unique=True)
price = models.IntegerField(_('Price'), blank=False)
available_from = models.TimeField(_('Available From'), default=datetime.time(6, 00), blank=False)
available_till = models.TimeField(_('Available till'), default=datetime.time(18, 00), blank=False)
description = models.TextField(_('Garage Description'), blank=True, null=True)
create_date = cmodels.UnixTimestampField(_('Date Added'), auto_now_add=True)
update_date = cmodels.UnixTimestampField(_('Date Added'), auto_created=True)
is_available = models.BooleanField(_('Available'), default=True)
序列化器
class UserFKSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ('id', 'name', 'email', 'mobile')
class GarageSerializer(serializers.ModelSerializer):
owner = UserFKSerializer(many=False, read_only=True)
class Meta:
model = GarageDetails
fields = '__all__'
read_only_fields = ('id', 'owner', 'create_date', 'update_date')
观看次数
class GarageRegister(generics.ListCreateAPIView):
renderer_classes = (JSONRenderer, )
permission_classes = (IsAuthenticated, )
@csrf_exempt
def post(self, request, *args, **kwargs):
serialize = GarageSerializer(data=request.data)
if serialize.is_valid():
# Create Garage with owner & name
class GarageUpdate(generics.ListCreateAPIView):
renderer_classes = (JSONRenderer, )
permission_classes = (IsAuthenticated, )
@csrf_exempt
def post(self, request, *args, **kwargs):
serialize = GarageSerializer(data=request.data)
if serialize.is_valid():
# Update Garage but can't update create_date, id, owner & name
【问题讨论】:
向我们展示您的模型、序列化程序和视图文件!然后我们可以更好地帮助你.. @AbijithMg 已添加,请查看 这能回答你的问题吗? Django Rest Framework: Disable field update after object is created @FranciscoCouzo 我的要求是不使用多个序列化程序。 【参考方案1】:您可以为每个用例(更新、创建)创建不同的模型序列化程序:
在您的模型序列化程序中指定 read_only_fields
中的该字段:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('a', 'nother', 'field')
read_only_fields = ('owner',)
对于 django 表单,您设置 disabled
field:
class MyModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
form.fields['owner'].widget.attrs['disabled'] = True
【讨论】:
如果owner
是序列化程序中的只读字段,OP 将如何创建模型?在问题中指定该字段仅在创建时需要,而不是更新时。
@AKS 每个用例都有两个模型序列化程序
github.com/encode/django-rest-framework/issues/1604 有同样的讨论..
@DRC 如果您认为使用两个模型序列化程序是可行的方法,您应该在答案中包含此信息。
我认为您还需要指定如何选择这些序列化程序之一以在视图中创建/更新案例。【参考方案2】:
您可以通过覆盖“更新”方法来做到这一点,如下所示:
def 更新(自我,实例,验证数据): 如果验证数据中的“所有者”: del 验证数据['所有者'] return super().update(instance, valid_data)这将在更新时默默地忽略所有者字段。如果你愿意,你可以改为“引发 ValidationError('owner may not be set on updates')”,但如果你这样做,你可能想要读取模型实例,并且只有在它实际上是为了避免误报而发生变化时才引发错误。
另外,如果您使用的是 python2,“super”调用需要是“super(GarageSerializer, self)”或类似的。
【讨论】:
以上是关于DJango REST Framework 只读字段的主要内容,如果未能解决你的问题,请参考以下文章
在 Django 和 Django REST Framework 中使用保留字“class”作为字段名
Django REST Framework 序列化程序字段必需=false
Django-rest-framework 和 django-rest-framework-jwt APIViews and validation Authorization headers
Django Rest Framework 和 django Rest Framework simplejwt 两因素身份验证