【问题标题】:DJango REST Framework Read Only fieldDJango REST Framework 只读字段
【发布时间】: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

【问题讨论】:

标签: django python-3.x django-rest-framework


【解决方案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 每个用例都有两个模型序列化程序
  • @DRC 如果您认为使用两个模型序列化程序是可行的方法,您应该在答案中包含此信息。
  • 我认为您还需要指定如何选择这些序列化程序之一以在视图中创建/更新案例。
【解决方案2】:

您可以通过覆盖“更新”方法来做到这一点,如下所示:

def 更新(自我,实例,验证数据): 如果验证数据中的“所有者”: del 验证数据['所有者'] return super().update(instance, valid_data)

这将在更新时默默地忽略所有者字段。如果你愿意,你可以改为“引发 ValidationError('owner may not be set on updates')”,但如果你这样做,你可能想要读取模型实例,并且只有在它实际上是为了避免误报而发生变化时才引发错误。

另外,如果您使用的是 python2,“super”调用需要是“super(GarageSerializer, self)”或类似的。

【讨论】:

    猜你喜欢
    • 2021-03-06
    • 2018-05-17
    • 2021-09-03
    • 2013-01-15
    • 2021-11-18
    • 2016-05-01
    • 2014-08-19
    • 2015-09-19
    • 1970-01-01
    相关资源
    最近更新 更多