Opened 7 years ago
Last modified 7 years ago
#29981 closed Bug
invalid_choice error when changing InlineModel with a OneToOne relation via to_field — at Initial Version
| 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
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 Meta:
verbose_name_plural = 'Entries'
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)
class AnotherEntryDetail(models.Model):
entry = models.OneToOneField(
Entry,
primary_key=True,
on_delete=models.CASCADE
)
otherdescription = models.TextField(blank=True, null=True)
admin.py
from django.contrib import admin
from .models import Entry, EntryDetail, AnotherEntryDetail
class EntryDetailInline(admin.StackedInline):
model = EntryDetail
class AnotherEntryDetailInline(admin.StackedInline):
model = AnotherEntryDetail
@admin.register(Entry)
class EntryAdmin(admin.ModelAdmin):
inlines = [
EntryDetailInline,
AnotherEntryDetailInline
]
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
Expected behavior:
In the admin:
- add an Entry
- fill slug and "Another entry detail" description
- save
- (change "Another entry detail" description)
- save
Steps to reproduce the bug:
In the admin:
- add an Entry
- fill slug and "Entry detail" description
- save
- (change "Entry detail" description)
- save
- Error message in admin: "Please correct the error below."
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
Sorry for the confusing ticket-title, i couldn't come up with something better.
Note:
See TracTickets
for help on using tickets.