Opened 68 minutes ago

Last modified 61 minutes ago

#37147 assigned Bug

Empty form for inlines breaks when using db_default on primary key field

Reported by: Mariusz Felisiak Owned by: Mariusz Felisiak
Component: Forms Version: 6.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Using db_default with the new UUID4 or UUID7 functions breaks saving inlines. For example,

  • models.py
    class MyMain(models.Model):
        uuid = models.UUIDField(primary_key=True, db_default=UUID7(), editable=False, verbose_name="UUID")
        name = models.CharField(max_length=100)
    
    class MyChild(models.Model):
        name = models.CharField(max_length=100)
        parent = models.ForeignKey(MyMain, models.DB_CASCADE)
    
  • admin.py
class ChildAdmin(admin.TabularInline):
    model = MyChild
    extra = 0


class MainAdmin(admin.ModelAdmin):
    inlines = [ChildAdmin]


admin.site.register(MyChild)
admin.site.register(MyMain, MainAdmin)

DatabaseDefault instances are rendered as values of the parent fields:

<tr class="form-row  empty-form" id="mychild_set-empty">
  <td class="original">      
     <input type="hidden" name="mychild_set-__prefix__-id" id="id_mychild_set-__prefix__-id">
     <input type="hidden" name="mychild_set-__prefix__-parent" value="&lt;django.db.models.expressions.DatabaseDefault object at 0x750a2aa14ad0&gt;" id="id_mychild_set-__prefix__-parent">
  </td>
  ...

which causes the following error when trying to save:

[{'parent': ['The inline value did not match the parent instance.']}]

Change History (1)

comment:1 by Mariusz Felisiak, 61 minutes ago

The following fixes this issue for me:

  • django/forms/widgets.py

    diff --git a/django/forms/widgets.py b/django/forms/widgets.py
    index f401896b60..140bd3e395 100644
    a b class Widget(metaclass=MediaDefiningClass):  
    343343        """
    344344        Return a value as it should appear when rendered in a template.
    345345        """
    346         if value == "" or value is None:
     346        from django.db.models.expressions import DatabaseDefault
     347
     348        if value == "" or value is None or isinstance(value, DatabaseDefault):
    347349            return None
    348350        if self.is_localized:
    349351            return formats.localize_input(value)
Note: See TracTickets for help on using tickets.
Back to Top