Opened 2 years ago

Closed 2 years ago

#33912 closed Bug (duplicate)

In the admin, saving an object in a non-default DB with unique field fails when the default DB contains an object with the same unique field value but different PK

Reported by: François Granade Owned by: nobody
Component: contrib.admin Version: 4.0
Severity: Normal Keywords: admin multi-db
Cc: François Granade Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by François Granade)

Reproducible using the test project in https://github.com/farialima/django-multidbbug . See README.md on how to run it.

The steps are:

  • a model with a unique string field (beside the default int PK)
  • two DBs in the settings (default and other)
  • two objects in the default DB with PK 1 and 2, and some unique value for the unique string field
  • a object in the other DB (thus, with PK 1) with a different unique string field value
  • in admin.py, point the UI to the other database for the model (using https://docs.djangoproject.com/en/4.0/topics/db/multi-db/#exposing-multiple-databases-in-django-s-admin-interface)
  • in the admin, try modifying the object in the other DB, giving it the same unique string value as the object with PK 2 in the default database

=> saving fails with error "Parcel with this Tracking id already exists.", see screenshot.

The underlying issue is clearly that the admin will try to verify in the default DB that the objects doesn't exist. I think that the admin should *not* look in the default DB, as I set it up to only use the 'other' DB for my model...

The issue only occurs in the admin, things are OK when editing the model objects in code:

 % poetry run ./manage.py shell
(...)
>>> from multidbbugapp.models import Parcel
>>> print(Parcel.objects.all())
<QuerySet [<Parcel: id=1, tracking_id=one>, <Parcel: id=2, tracking_id=two>]>
>>> print(Parcel.objects.using('other').all())
<QuerySet [<Parcel: id=1, tracking_id=two-duplicate>]>
>>> o = Parcel.objects.using('other').first()
>>> o
<Parcel: id=1, tracking_id=two-duplicate>
>>> o.tracking_id = 'two'
>>> o.save()
>>> 

Attachments (2)

Screen Shot 2022-08-10 at 12.07.45 PM.png (103.9 KB ) - added by François Granade 2 years ago.
screenshot of the error
patch_33912.diff (1.1 KB ) - added by François Granade 2 years ago.
simple patch that fixes the problem. See comments on why it doesn't include a test (yet..)

Download all attachments as: .zip

Change History (6)

by François Granade, 2 years ago

screenshot of the error

comment:1 by François Granade, 2 years ago

Cc: François Granade added
Component: Uncategorizedcontrib.admin
Description: modified (diff)
Keywords: admin multidb added
Type: UncategorizedBug

comment:2 by François Granade, 2 years ago

Keywords: multi-db added; multidb removed
Summary: In the admin, saving an object in a non-default database with unique field fails when the default database contains an object with the same unique field value but different PKIn the admin, saving an object in a non-default DB with unique field fails when the default DB contains an object with the same unique field value but different PK

This may be caused by (and somewhat a simple test case of) https://code.djangoproject.com/ticket/15130 ?

comment:3 by François Granade, 2 years ago

indeed, that's the same issue as #15130 . I'm attaching a patch that fixes it , but it doesn't include a test.

I can write a test to get the patch accepted, but I would need some guidance on writing the test: I cannot find example of tests that deal with the admin *and* with multiple database, so I don't know how to write it... Could someone with experience point me to some example of tests I could copy/reuse, or to a general idea of how to write a test on the admin with multiple databases ? Thanks in advance.

by François Granade, 2 years ago

Attachment: patch_33912.diff added

simple patch that fixes the problem. See comments on why it doesn't include a test (yet..)

comment:4 by Mariusz Felisiak, 2 years ago

Resolution: duplicate
Status: newclosed

Duplicate of #15130. Please leave comments in the original ticket.

Note: See TracTickets for help on using tickets.
Back to Top