django rest框架中的只读、写字段

django rest框架中的只读、写字段,django,django-rest-framework,Django,Django Rest Framework,我有这样的模型: class ModelA(models.Model): name = models.CharField() class ModelB(models.Model): f1 = models.CharField() model_a = models.ForeignKey(ModelA) 序列化程序: class ASerializer(serializers.ModelSerializer): model_b_ids = serializers

我有这样的模型:

class ModelA(models.Model):
    name = models.CharField()


class ModelB(models.Model):
    f1 = models.CharField()
    model_a = models.ForeignKey(ModelA)
序列化程序:

class ASerializer(serializers.ModelSerializer):
    model_b_ids = serializers.CharField()
    class Meta:
        model = ModelA
        write_only_fields = ('model_b_ids',)
观点:

class AView(CreateModelMixin, GenericViewSet):

    def perform_create(self, serializer): 
        model_b_ids = parse_somehow(serializer.validated_data["model_b_ids"])
        #do something...
我遇到的问题是“model_b_id”的问题

用户应在发送post数据时提交

我在perform_create中使用它链接到相关模型

但这不是ModelA中的“真实列”,所以当我试图保存它时,会引发异常


我试图从已验证的_数据中弹出它,但在无法从模型中读取模型_b_id的地方再次出现错误。有没有正确使用此类字段的想法?

可能您正在监督您的
ModelA
是否具有
modelbu集的属性。在Django中,您在一个模型类中描述关系。Django通过降低目标模型的大小写并用
\u set
作为后缀,提供了一种向后关系。所以你可以做:

a = ModelA.objects.get(pk=1)
a.modelb_set.all()
这将从ModelA获取ID(或主键)为1的元素,并检索所有相关的ModelB元素

您可以为
相关\u name
设置一个值以覆盖默认值:

class ModelB(models.Model):
    f1 = models.CharField()
    model_a = models.ForeignKey(ModelA, related_name='model_b')
在DRF中,您可以稍微调整序列化程序:

class ASerializer(serializers.ModelSerializer):
    model_b = serializers.PrimaryKeyRelatedField(many=True, read_only=False)

    class Meta:
        model = ModelA
        write_only_fields = ('model_b',)
使用
serializers.CharField()
时,您不能发布值并将其写入模型,因为它不是模型字段

试试这个例子。修补和实验。这会让你更接近解决方案

编辑:
我不确定Django是如何为PascalCase类名称的向后关系创建名称的。是
ModelB
modelbu集吗?或者它是
modelbu集
?您可以尝试找到它。

您可以重写ASerializer上的serializer.save()方法来实例化modelA对象,设置其属性,保存它,然后在现有modelB对象上设置关系,保存它们,并为成功干杯。
但我认为,在序列化程序上设置相关的_名称和RelatedField(如建议的)可能会做完全相同的事情。。。。少打字。。总体来说更好:)

Django Rest框架不再具有元属性
只写字段

根据他们的设置额外的\u kwargs中的只写字段

e、 g


根据Django REST框架:

ModelSerializer上的write_only_fields选项已移动到PendingDeprecation,并替换为更通用的extra_kwargs

这就是为什么建议这样做:您应该使用额外的_-kwargs:

extra_kwargs = {
    'model_b_ids': {'write_only': True},
    'another_field': {'read_only': True}
}
或:

从中,您可以使用
只读

只读字段包含在API输出中,但在创建或更新操作期间不应包含在输入中。序列化程序输入中错误包含的任何“只读”字段都将被忽略

将此设置为True,以确保在序列化表示时使用该字段,但在反序列化期间创建或更新实例时不使用该字段

默认值为
False

例如:

我们可以在序列化程序字段上使用它:

model_b_ids = serializers.IntegerField(read_only=True)
或者我们可以在
extra_-kwargs
中使用它:

extra_kwargs = {
    'model_b_ids': {'read_only': True}
}

我刚刚将DRF从3.1.3更新到3.3.3,突然我的用户密码被发回(我在
只写
Meta atribute之前就有了)。你的解决方案解决了这个问题。谢谢!@vabada我希望你的意思是hashes Ellusive,但这是Django 3.1中的工作方式
model_b_ids = serializers.IntegerField(read_only=True)
extra_kwargs = {
    'model_b_ids': {'read_only': True}
}