django-nested-admin icon indicating copy to clipboard operation
django-nested-admin copied to clipboard

Unique field conflict on moving this field

Open sSimuSs opened this issue 4 years ago • 5 comments

I have two models relating each other (Group and GroupItems). GroupItems has a unique SlugField. This unique field conflicts when I attempting to move (drag-and-drop) it to another group as its child. As I know when you moving child items js creates new one with the moving item's data, but when you saving system says "GroupItems with this Slug already exists."

sSimuSs avatar May 26 '20 04:05 sSimuSs

Are you using MySQL by any chance? What version?

fdintino avatar May 31 '20 21:05 fdintino

Does it depend on the type of database? As I understand it, when you drag it into another group, it is not deleted in the old one yet and as a result the system says that it is duplicated. I'm using sqlite3

sSimuSs avatar Jun 01 '20 04:06 sSimuSs

I asked about the database backend because this can be avoided in Postgres with deferrable unique constraints. I had mistakenly thought this was also available in sqlite, but that doesn't appear to be the case (and besides, Django only added support for this feature in postgres 5 weeks ago).

I'm actually not sure how I could go about fixing this in django-nested-admin. One possibility might be to perform inline form delete operations first within the save transaction; I'm trying to think through whether that could break anything else.

fdintino avatar Jun 01 '20 05:06 fdintino

I think so either, firstly should go deleting the old one, then saving the moved one.

In my opinion when dragging it is not necessary to remove the old one but just hide and check delete

sSimuSs avatar Jun 01 '20 07:06 sSimuSs

Actually, it occurs to me that django doesn't actually store uniqueness constraints in the database, but enforces uniqueness in code. It might be possible to override BaseModelFormSet.validate_unique to make it compatible with moving between nested inlines.

I'm reminded of why it isn't as simple as hiding and checking delete on the form: suppose that the inline being moved has child inlines of its own: we would need to recursively recreate the children, since they would be cascade deleted during the save. We would also then need to be able to retrieve the original primary key and foreign key references if the inline were dragged back to the original parent. We couldn't simply undelete the original, since changes might have been made during the time it had a different parent.

That's not to say that it couldn't be done, but it would be a fairly involved change. Whereas we might be able to define a custom NestedInlineFormSetMixin.validate_unique that solves this particular issue without needing to make large changes to the drag-and-drop splicing logic in javascript.

fdintino avatar Jun 01 '20 18:06 fdintino