* status: closed => new
* severity: => Normal
* resolution: wontfix =>
* easy: => 0
* ui_ux: => 0
* type: => Bug
Comment:
I just had to deal with the original Problem: ''Row duplicated when
modifying PK''
By changing the primary key in admin you can also get another problem: If
the model has another unique field, then you get the admin error that the
field value is not unique. (This is because django tries to create a
duplicated entry).
The problem is: {{{django.forms.models.BaseModelForm._post_clean()}}} will
do this:
{{{
self.instance = construct_instance(self, self.instance, opts.fields,
opts.exclude)
}}}
And {{{construct_instance()}}} will just change the primary key and this
object will be saved in the end and results in duplication. This is a
known behaviour as the docs says at:
https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.Field.primary_key
If you change the value of the primary key on an existing object and
then save it, a new object will be created alongside the old one.
One way to change the primary key is:
{{{
FooBarModel.objects.filter(id=old_id).update(id=new_id)
}}}
My current work-a-round it to use a own model form:
{{{
class FooBarAdminForm(forms.ModelForm):
def clean_id(self):
old_id = self.instance.id
new_id = self.cleaned_data['id']
if old_id == new_id:
# ID not changed -> nothing to do
return old_id
if FooBarModel.objects.filter(id=new_id).exists():
raise forms.ValidationError('ID already exists')
# Change the primary key without make a new object:
FooBarModel.objects.filter(id=old_id).update(id=new_id)
# replace new created instance, made in self._post_clean() via
construct_instance():
self.instance = FooBarModel.objects.get(id=new_id)
return new_id
}}}
But that's not a perfect solution:
* It's not universal. (Primary key must be {{{id}}})
* Has potential for race-contitions
* Admin ''continue'' will redirect to {{{request.path}}} that will contain
the old ID (But can be fixed via overwriting {{{response_change()}}})
--
Ticket URL: <https://code.djangoproject.com/ticket/14071#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: jedie (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/14071#comment:3>
* status: new => closed
* resolution: => wontfix
Comment:
[https://docs.djangoproject.com/en/stable/internals/contributing/triaging-
tickets/#closing-tickets Please follow triaging guidelines with regards to
wontfix tickets.]
--
Ticket URL: <https://code.djangoproject.com/ticket/14071#comment:4>