-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Open
Description
I've got a KeyError on line condition_kwargs = {source: attrs[source] for source in condition_sources}
in the __call__
method of UniqueTogetherValidator
class validating unique constraint with condition during partial update, because the condition field was not in attrs:
def __call__(self, attrs, serializer):
self.enforce_required_fields(attrs, serializer)
queryset = self.queryset
queryset = self.filter_queryset(attrs, queryset, serializer)
queryset = self.exclude_current_instance(attrs, queryset, serializer.instance)
checked_names = [
serializer.fields[field_name].source for field_name in self.fields
]
# Ignore validation if any field is None
if serializer.instance is None:
checked_values = [attrs[field_name] for field_name in checked_names]
else:
# Ignore validation if all field values are unchanged
checked_values = [
attrs[field_name]
for field_name in checked_names
if attrs[field_name] != getattr(serializer.instance, field_name)
]
condition_sources = (serializer.fields[field_name].source for field_name in self.condition_fields)
condition_kwargs = {source: attrs[source] for source in condition_sources} # here is the issue
if checked_values and None not in checked_values and qs_exists_with_condition(queryset, self.condition, condition_kwargs):
field_names = ', '.join(self.fields)
message = self.message.format(field_names=field_names)
raise ValidationError(message, code='unique')
I assume that if source
is not present in attrs
, it should fall back to getattr(serializer.instance, source)
, something like:
condition_kwargs = {}
for source in condition_sources:
if source in attrs:
condition_kwargs[source] = attrs[source]
elif serializer.instance is not None:
condition_kwargs[source] = getattr(serializer.instance, source)
Similarly as this is done in the 'filter_queryset' method.
Metadata
Metadata
Assignees
Labels
No labels