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}
}