theatlantic / django-nested-admin

Django admin classes that allow for nested inlines
http://django-nested-admin.readthedocs.org/
Other
714 stars 99 forks source link

Unique field conflict on moving this field #179

Open sSimuSs opened 4 years ago

sSimuSs commented 4 years ago

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."

fdintino commented 4 years ago

Are you using MySQL by any chance? What version?

sSimuSs commented 4 years ago

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

fdintino commented 4 years ago

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.

sSimuSs commented 4 years ago

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

fdintino commented 4 years ago

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.