Opened 6 years ago

Last modified 5 years ago

#29981 closed Bug

"Please correct the error below." (with no errors displayed) when changing an inline that has a one-to-one relation to the parent that uses to_field — at Version 1

Reported by: Bernie Owned by: nobody
Component: contrib.admin Version: 2.1
Severity: Normal Keywords:
Cc: Sergey Fedoseev Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Tim Graham)

Code sample:

models.py:

from django.db import models

class Entry(models.Model):
    slug = models.SlugField(max_length=80, unique=True)
    title = models.CharField(max_length=255, blank=True, null=True)

class EntryDetail(models.Model):
    entry = models.OneToOneField(
        Entry,
        to_field='slug',
        primary_key=True,
        on_delete=models.CASCADE
    )
    description = models.TextField(blank=True, null=True)

admin.py

from django.contrib import admin
from .models import Entry, EntryDetail

class EntryDetailInline(admin.StackedInline):
    model = EntryDetail

@admin.register(Entry)
class EntryAdmin(admin.ModelAdmin):
    inlines = [EntryDetailInline]

    def get_readonly_fields(self, request, obj=None):
        # Even with EntryDetail.entry_id ON UPDATE: CASCADE set on DB-level
        # changing Entry.slug through the admin-change-form with EntryDetail-inline fails.
        # Set slug readonly as workaround. Don't know if this is worth fixing.
        readonly_fields = super().get_readonly_fields(request, obj)
        if hasattr(obj, 'entrydetail') and 'slug' not in readonly_fields:
            readonly_fields += ('slug',)
        return readonly_fields

Steps to reproduce the bug:

In the admin:

  • add an Entry
  • fill slug, title, and "Entry detail" description
  • save and continue editing
  • change "Entry detail" description
  • save
  • Error message in admin: "Please correct the error below." (with no errors listed). formset[0].errors is [{'entry': ['The inline value did not match the parent instance.']}] which comes from InlineForeignKeyField value is aaa and orig is 1.

Workaround:

in models.py replace

class EntryDetailInline(admin.StackedInline):
    model = EntryDetail

with:

from django.forms import BaseInlineFormSet

class EntryDetailFormSet(BaseInlineFormSet):
    def add_fields(self, form, index):
        super().add_fields(form, index)
        related_name = self._pk_field.remote_field.related_name or self._pk_field.remote_field.name
        if hasattr(self.instance, related_name):
            form.fields[self._pk_field.name].to_field = self._pk_field.remote_field.field_name

class EntryDetailInline(admin.StackedInline):
    model = EntryDetail
    formset = EntryDetailFormSet

Change History (1)

comment:1 by Tim Graham, 6 years ago

Description: modified (diff)
Summary: invalid_choice error when changing InlineModel with a OneToOne relation via to_field"Please correct the error below." (with no errors displayed) when changing an inline that has a one-to-one relation to the parent that uses to_field
Triage Stage: UnreviewedAccepted

I reproduced the issue on master (78fc64578a8715b9812075bbebc829c1251c07fa). I removed AnotherEntryDetailInline from the description as it doesn't seem required to reproduce the issue.

Note: See TracTickets for help on using tickets.
Back to Top