Opened 2 years ago

Last modified 2 years ago

#20301 new Bug

Unique field validation with multiple DB connections.

Reported by: SardarNL Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

django.db.models.base._perform_unique_checks is not using self._state.db to lookup unique fields. Check the following:

class MyModel(models.Model):
   my_unique = models.IntegerField(unique=True)

obj = MyModel(my_unique=value_exists_on_default_new_on_other_connection)
obj._state.db = other_connection
obj.full_clean()

# for existing objects _state.db will be already set
obj = MyModel.objects.using(other_connection).get(pk=existing)
obj.my_unique = value_exists_on_default_new_on_other_connection
obj.full_clean()

full_clean() will validate_unique() -> _perform_unique_checks(), which will eventually qs = model_class._default_manager.filter(**lookup_kwargs). The default manager is always using default connection, so unique check will be performed on default connection. Other validators, such as ForeignKey lookup, properly use .using() to keep talking to the database where the object came from.

Fix: qs = model_class._default_manager.filter(**lookup_kwargs).using(self._state.db)
The same fix is needed for _perform_date_checks().

Change History (1)

comment:1 Changed 2 years ago by jacob

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted
Note: See TracTickets for help on using tickets.
Back to Top