Reputation: 745
I have a field owner
that is a ForeignKey
to User
model.
This field is required
at the time of creation. But it can not be changed later on.
How to make fields Non-Editable
? Is there any other way than creating multiple serializers?
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
Upvotes: 11
Views: 12270
Reputation: 456
You can do this by overriding the "update" method as follows:
def update(self, instance, validated_data): if 'owner' in validated_data: del validated_data['owner'] return super().update(instance, validated_data)
This will silently ignore the owner field on updates. If you want to you may instead "raise ValidationError('owner may not be set on updates')" but if you do so you may want to read the model instance and only raise the error if it's actually a change to avoid false positives.
Also, if you're using the python2, the "super" call needs to be "super(GarageSerializer, self)" or some such.
Upvotes: 1
Reputation: 5048
You could create a different model serializer for each use case (update, create):
specifying that field in read_only_fields
in your model serializer:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('a', 'nother', 'field')
read_only_fields = ('owner',)
for django forms instead you set the disabled
field:
class MyModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
form.fields['owner'].widget.attrs['disabled'] = True
Upvotes: 6