I needed to validate a model field to be unique as lower case, but without actually saving the model field in lower case; e.g. if someone has already taken the username 'david', then the username 'David' would not be available. I tried various things, and eventually ended up doing the following:
def _perform_unique_checks(self, unique_checks): errors = {} for model_class, unique_check in unique_checks: lookup_kwargs = {} for field_name in unique_check: f = self._meta.get_field(field_name) lookup_value = getattr(self, f.attname) if lookup_value is None: continue if f.primary_key and not self._state.adding: continue lookup_kwargs[str(field_name)] = lookup_value if len(unique_check) != len(lookup_kwargs): continue if 'username' in lookup_kwargs: lookup_kwargs['username'] = lookup_kwargs['username'].lower() qs = model_class._default_manager.filter(**lookup_kwargs) model_class_pk = self._get_pk_val(model_class._meta) if not self._state.adding and model_class_pk is not None: qs = qs.exclude(pk=model_class_pk) if qs.exists(): if len(unique_check) == 1: key = unique_check[0] else: key = NON_FIELD_ERRORS errors.setdefault(key, []).append( self.unique_error_message(model_class, unique_check)) ... which works, but feels a little convoluted to me. I wondered whether any there's a more succinct way of achieving this?