#28831 closed Cleanup/optimization (fixed)
Document that InlineModelAdmin methods' obj argument is the parent object.
| Reported by: | Artem Skoretskiy | Owned by: | Parth Patil |
|---|---|---|---|
| Component: | Documentation | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | tonn81@…, Manel Clos | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
When I use ModelAdmin.get_fieldsets, I receive current object. In my example that would be -- when I call AccountAdmin.get_fieldsets -- I receive Account. That enable me to generate different field sets for different cases.
BUT when I use InlineModelAdmin.get_fieldsets, I receive parent object. In my example that would be -- when I call
AccountInline.get_fieldsets -- I receive Customer object instead of `Account. That prevents me from configuring formsets to the account I have.
If I received Account, I could extract Customer from it. But if I receive Customer, I cannot adapt form for each row.
Also, it seems strange that class explicitly linked to Account receives Customer object as input.
Code:
# in models.py
class Customer(models.Model):
num = models.IntegerField()
class Account(models.Model):
ACCOUNT_TYPES = (
(1, 'A'),
(2, 'B'),
)
customer = models.ForeignKey(Customer)
account_type = models.IntegerField(choices=ACCOUNT_TYPES)
a = models.CharField(max_length=255, blank=True) # should be edited when type = "A"
b = models.CharField(max_length=255, blank=True) # should be edited when type = "B"
# in admin.py
class AccountInline(admin.TabularInline):
model = models.Account
def get_fieldsets(self, request, obj=None):
print(repr(obj)) # => <Customer>
"""
if obj and obj.account_type == 1:
return ((None, {'fields': ('account_type', 'a')}),)
elif obj and obj.account_type == 2:
return ((None, {'fields': ('account_type', 'b')}),)
"""
return ((None, {'fields': ('account_type',)}),)
@admin.register(models.Customer)
class CustomerAdmin(admin.ModelAdmin):
inlines = (AccountInline,)
@admin.register(models.Account)
class AccountAdmin(admin.ModelAdmin):
def get_fieldsets(self, request, obj=None):
print(repr(obj)) # => <Account>
if obj and obj.account_type == 1:
return ((None, {'fields': ('account_type', 'a')}),)
elif obj and obj.account_type == 2:
return ((None, {'fields': ('account_type', 'b')}),)
return ((None, {'fields': ('account_type',)}),)
Change History (7)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
| Component: | contrib.admin → Documentation |
|---|---|
| Summary: | InlineModelAdmin.get_fieldsets should receive own object, not parent → Document that InlineModelAdmin methods' obj argument is the parent object |
| Triage Stage: | Unreviewed → Accepted |
| Type: | Bug → Cleanup/optimization |
I don't believe changing the behavior is possible and of course it would also be backwards incompatible. Perhaps the documentation could clarify the current behavior.
comment:3 by , 8 years ago
| Cc: | added |
|---|
comment:4 by , 6 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:5 by , 6 years ago
| Has patch: | set |
|---|---|
| Summary: | Document that InlineModelAdmin methods' obj argument is the parent object → Document that InlineModelAdmin methods' obj argument is the parent object. |
| Version: | 2.0 → master |
By the way, custom fields on inline admins receive correct object:
class AccountInline(admin.TabularInline): ... def type_verbose(self, obj): return "Account is {}".format(obj.get_account_type_display()) type_verbose.short_description = "Account type"