Reputation: 456
When a new client is created, I need them to send back 'confirm_domain_url' so that I can do a check on whether or not it equals 'domain_url'. I call serializer.is_valid() in the create method and it works as intended. When a client is updated, it fails saying that 'domain_url' is missing. I know I can just create a new serializer for the update method but I would like to consolidate as much code as I can.
Serializer:
class ClientSerializer(ModelSerializer):
confirm_domain_url = CharField(write_only=True)
class Meta:
model = Client
fields = [
'name',
'schema_name',
'domain_url',
'created_on',
'id',
# Write only fields (won't be returned in the response):
'confirm_domain_url',
]
def validate(self, data):
# Check that domain urls match:
if data['domain_url'] != data['confirm_domain_url']:
raise ValidationError('Domain urls do not match.')
return data
def create(self, validated_data):
client = Client(
name = validated_data['name'],
schema_name = validated_data['schema_name'],
domain_url = validated_data['domain_url'],
)
client.save()
return client
ViewSet:
class ClientViewSet(viewsets.ViewSet):
def list(self, request):
queryset = Client.objects.all()
serializer = ClientSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = Client.objects.all()
client = get_object_or_404(queryset, pk=pk)
serializer = ClientSerializer(client)
return Response(serializer.data)
def create(self, request):
serializer = ClientSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
def update(self, request, pk=None):
queryset = Client.objects.all()
client = queryset.get(pk=pk)
serializer = ClientSerializer(client, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
Upvotes: 0
Views: 48
Reputation: 8026
We can add a check to the ClientSerializer.validate
method which checks if the instance
attribute has been assigned to the serializer. If an instance has been defined on the serializer then it would be an update operation, otherwise it would not have an instance to update. So this will only check domain_url
against confirm_domain_url
when creating.
class ClientSerializer(ModelSerializer):
...
def validate(self, data):
# Check that domain urls match:
if self.instance is None and data['domain_url'] != data['confirm_domain_url']:
raise ValidationError('Domain urls do not match.')
return data
...
edit - I changed the logical order of the if statement in the validate method. The problem was it was trying to access data['domain_url']
in the first part of the conditional, leading to a KeyError. Now that it checks for self.instance is None
first, this will short-circuit the if statement and it wont try to access data['domain_url']
if an instance is defined.
Upvotes: 2