DJango REST Framework 只读字段

Posted

技术标签:

【中文标题】DJango REST Framework 只读字段【英文标题】:DJango REST Framework Read Only field 【发布时间】:2017-08-29 12:36:13 【问题描述】:

我有一个字段owner,它是ForeignKeyUser 的模型。

此字段在创建时为 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 两因素身份验证

怎么安装django rest framework

django rest framework中文介绍