Django Rest Framework在创建记录后将字段设置为read_only [英] Django Rest Framework set a field read_only after record is created
问题描述
我正在使用 Django 2.x
和 Django REST Framework
。
我有一个使用联系人
作为外键的模型
I have a model with contact
as a foreign key
class AmountGiven(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
amount = models.FloatField(help_text='Amount given to the contact')
given_date = models.DateField(default=timezone.now)
created = models.DateTimeField(auto_now=True)
和序列化程序,如
class AmountGivenSerializer(serializers.ModelSerializer):
mode_of_payment = serializers.PrimaryKeyRelatedField(queryset=ModeOfPayment.objects.all())
contact_detail = ContactSerializer(source='contact', read_only=True)
contact = serializers.PrimaryKeyRelatedField(queryset=Contact.objects.all())
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'contact_detail', 'amount', 'given_date', 'created'
)
contact
字段。但是我不希望联系人
创建后就对其进行修改。
contact
field is required while creating a new record. But I do not want contact
to be modified once it is created.
但是当我仅发送金额
使用 PUT
方法表示
But when I send only amount
with PUT
method it says
{
"contact": [
"This field is required."
]
}
当我使用 PATCH时
方法,它可以正常工作,但是如果为 contact
传递其他值,它将更新 contact
And when I use PATCH
method, it works fine but if passing some other value for contact
, it is updating contact
as well.
我想建立联系人
字段不需要
,同时更新现有记录。即使已通过,也请使用较早的版本,而不要设置新数据。
I want to make contact
field not-required
while updating existing record. And even if it is passed, use the earlier one instead of setting the new data.
试用2
Trial 2
我尝试将请求中的 contact
字段覆盖为先前存储的值,以防万一如果更改了联系人
,或者没有通过联系人
,它将保存较早的联系人。
I tried overriding the contact
field in the request to the previously stored value so that in case if changed contact
is passed or no contact
is passed, it will save earlier one.
因此,在视图集中添加函数
So, in the viewset add the function
def update(self, request, *args, **kwargs):
obj = self.get_object()
request.data['contact'] = obj.contact_id
return super().update(request, *args, **kwargs)
但这给出了错误,因为
This QueryDict instance is immutable
推荐答案
使用序列化器的 __ init __
方法使其在对象更新时读取:
Use __init__
method of serializer to make it read when object is being updated:
class AmountGivenSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
"""If object is being updated don't allow contact to be changed."""
super().__init__(*args, **kwargs)
if self.instance is not None:
self.fields.get('parent').read_only = True
# self.fields.pop('parent') # or remove the field
mode_of_payment = serializers.PrimaryKeyRelatedField(queryset=ModeOfPayment.objects.all())
contact_detail = ContactSerializer(source='contact', read_only=True)
contact = serializers.PrimaryKeyRelatedField(queryset=Contact.objects.all())
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'contact_detail', 'amount', 'given_date', 'created'
)
使用 self.context ['view']。action
不建议使用,因为使用Serializ时它将不起作用超出DRF,例如在常规Django视图中。最好使用 self.instance
,因为它在每种情况下都可以使用。
Using self.context['view'].action
is not recommended as it will not work when using the serializer out of DRF, eg. in normal Django views. It's best to use self.instance
as it will work in every situation.
这篇关于Django Rest Framework在创建记录后将字段设置为read_only的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!