Opened 5 years ago
Closed 2 years ago
#32210 closed Bug (fixed)
Django Admin with Inlines not using UUIDField default value
| Reported by: | Joseph Metzinger | Owned by: | Neeraj Kumar |
|---|---|---|---|
| Component: | Forms | Version: | 4.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Neeraj Kumar, David Wobrock | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Hello,
I am a long time django user, first time bug reporter, so please let me know if I need to do anything else to help get this bug fixed :)
I am using Django 3.1.3 and python 3.8.5 and have cerated a toy project to illustrate the bug. I have the following models:
class UUIDModel(models.Model):
pkid = models.BigAutoField(primary_key=True, editable=False)
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
class Meta:
abstract = True
class Thing(UUIDModel):
name = models.CharField(max_length=191)
class SubThing(models.Model):
name = models.CharField(max_length=191)
thing = models.ForeignKey(
'bugapp.Thing',
to_field='id',
on_delete = models.CASCADE,
related_name='subthings',
)
And the following admin.py file:
class SubThingInline(admin.StackedInline):
model = SubThing
@admin.register(Thing)
class ThingAdmin(admin.ModelAdmin):
list_display = ('name',)
ordering = ('pkid',)
inlines = (SubThingInline,)
When logging into the admin, if you delete all of the entries for "subthings", add a name, and save the model, it will work. As soon as you try to add a subthing alongside the main Thing, it fails with the following exception:
It shows that the value of "id" in the Thing model is being set to null.
I believe this is a bug in django.
Thanks!
Attachments (1)
Change History (20)
by , 5 years ago
| Attachment: | bugdemo.tbz added |
|---|
comment:1 by , 5 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 5 years ago
| Component: | contrib.admin → Forms |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
Thanks for the detailed report. I was able to reproduce this issue. It looks that formsets' validation mutates the main object, because new_object.id is not empty before the all_valid() call:
>>> new_object.id e13fd82c-c3fc-42dc-ac12-577a4412ba51 >>> all_valid(formsets) True >>> new_object.id None
Reproduced at ead37dfb580136cc27dbd487a1f1ad90c9235d15.
comment:3 by , 4 years ago
Looks like it's not directly related to formsets' validation but instantiating formset's forms.
(Pdb) new_object.id
UUID('06048350-3ad9-45f5-bca3-d08d795d7231')
(Pdb) formsets[0].forms
[<SubThingForm bound=True, valid=Unknown, fields=(name;thing;id;DELETE)>]
(Pdb) new_object.id
(Pdb)
(Pdb) new_object.id
UUID('652863a7-ccc8-4a18-9390-6fb77aa4bafa')
(Pdb) formsets[0]._construct_form(0)
<SubThingForm bound=True, valid=Unknown, fields=(name;thing;id;DELETE)>
(Pdb) new_object.id
(Pdb)
comment:4 by , 3 years ago
| Owner: | removed |
|---|---|
| Status: | new → assigned |
comment:5 by , 3 years ago
The below code set id value None when formsets is_valid calling. so need to stop set id value None when that field is not model's pk as UUIDField.
if self.instance._state.adding:
if kwargs.get("to_field") is not None:
to_field = self.instance._meta.get_field(kwargs["to_field"])
else:
to_field = self.instance._meta.pk
if to_field.has_default():
setattr(self.instance, to_field.attname, None)
comment:6 by , 3 years ago
| Owner: | set to |
|---|
comment:8 by , 3 years ago
| Cc: | added |
|---|
comment:9 by , 3 years ago
| Cc: | added |
|---|---|
| Needs tests: | set |
| Patch needs improvement: | set |
comment:10 by , 3 years ago
| Needs tests: | unset |
|---|---|
| Patch needs improvement: | unset |
comment:11 by , 3 years ago
| Needs tests: | set |
|---|
comment:12 by , 3 years ago
| Needs tests: | unset |
|---|
comment:13 by , 3 years ago
| Needs tests: | set |
|---|
comment:15 by , 2 years ago
| Version: | 3.1 → 4.2 |
|---|
Any update about this issue?
Added PR related to this issue.
This issue still exists in the latest version of Django.
comment:16 by , 2 years ago
| Needs tests: | unset |
|---|
Resetting the PR flags to ensure the new PR gets picked up in the review queue.
comment:17 by , 2 years ago
| Needs tests: | set |
|---|---|
| Patch needs improvement: | set |
comment:18 by , 2 years ago
| Needs tests: | unset |
|---|---|
| Patch needs improvement: | unset |
| Triage Stage: | Accepted → Ready for checkin |
I made a toy project containing all the code to reproduce the error and zipped it.