Opened 14 years ago
Closed 14 years ago
#14095 closed (invalid)
Objects not saved when readonly_fields is set for inline admin
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | contrib.admin | Version: | 1.2 |
Severity: | Keywords: | TabularInline, inline, readonly_fields, sprintdec2010 | |
Cc: | simon@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Code
models.py:
class BalanceCode(models.Model): created_at = models.DateField(auto_now_add=True) code = models.CharField(max_length=BALANCE_CODE_LENGTH, unique=True, default=generate_balance_code, help_text=code_help) value = models.PositiveIntegerField(default=BALANCE_CODE_DEFAULT_VALUE) refill_series = models.ForeignKey(RefillSeries) used_by = models.ForeignKey(Student, null=True, blank=True) used_at = models.DateField(blank=True, null=True)
class RefillSeries(models.Model): issued = models.DateField(default=default_issued) least_valid_until = models.DateField(default=default_least_valid_until)
admin.py:
class BalanceCodeInline(admin.TabularInline): readonly_fields = ('code', ) model = BalanceCode extra = SERIES_CODE_COUNT max_num = SERIES_CODE_COUNT
class BalanceCodeAdmin(admin.ModelAdmin): readonly_fields = ('code', )
class RefillSeriesAdmin(admin.ModelAdmin): inlines = (BalanceCodeInline,)
Problem Description
Expected
When a new RefillSeries
is created, SERIES_CODE_COUNT BalanceCode
s should
be created as well.
Actual
No BalanceCode
s are created. When readonly_fields
is unset,
SERIES_CODE_COUNT
objects are created, as expected.
Creating new BalanceCode
s directly (not inlined in the RefillSeries
admin
interface) works as expected when readonly_fields
is set.
Change History (2)
comment:1 by , 14 years ago
comment:2 by , 14 years ago
Keywords: | sprintdec2010 added |
---|---|
Resolution: | → invalid |
Status: | new → closed |
Thank you for the report, Simon. It is true that Django is behaving oddly here. However, this is caused by the way inlines are currently designed to work. If you make the code
field readonly, then there will not be any input added to the form for it, which means that Django has no way of detecting that anything has changed in the form, and therefore cannot know that an object should be created.
I've discussed this at length with russelm and DrMeers (both core committers), and the answer is that this cannot be fixed. To achieve what you want you'd probably have to not make the code
field readonly, and then use a bit of javascript to prevent the user from modifying it.
For that reason I'm closing this ticket as invalid. I also invite you to look into ticket #14832, which has in fact emerged after looking at this one and which discusses a related issue.
Finally, for the record, here's the code I've used to study this issue (some elements like generate_balance_code
or SERIES_CODE_COUNT
were missing in your description):
Models:
import datetime, hashlib from django.db import models from django.contrib.auth.models import User def generate_balance_code(): return hashlib.md5(str(datetime.datetime.now())).hexdigest() class RefillSeries(models.Model): issued = models.DateField(default=datetime.datetime.today) least_valid_until = models.DateField(default=datetime.datetime.today() + datetime.timedelta(days=10000)) class BalanceCode(models.Model): created_at = models.DateField(auto_now_add=True) code = models.CharField(max_length=100, unique=True, default=generate_balance_code,) value = models.PositiveIntegerField(default=10) refill_series = models.ForeignKey(RefillSeries) used_by = models.ForeignKey(User, null=True, blank=True) used_at = models.DateField(blank=True, null=True)
Admin:
from django.contrib import admin from .models import BalanceCode, RefillSeries class BalanceCodeAdmin(admin.ModelAdmin): readonly_fields = ('code', ) class BalanceCodeInline(admin.TabularInline): readonly_fields = ('code', ) model = BalanceCode extra = 2 max_num = 5 class RefillSeriesAdmin(admin.ModelAdmin): inlines = [BalanceCodeInline] admin.site.register(BalanceCode, BalanceCodeAdmin) admin.site.register(RefillSeries, RefillSeriesAdmin)
Addendum: The inlined
BalanceCode
s show up in the admin interface, but they are not saved to database.