假设我在admin.py
中有以下内容:
class ImageInline(admin.TabularInline):
model = Image
class ObjectAdmin(admin.ModelAdmin):
inlines = [ ImageInline, ]
如何向ImageInline
模型中不是字段的Image
添加额外字段?
答案 0 :(得分:4)
与使用普通ModelAdmin的方法相同。 InlineModelAdmin可以接受表单属性it's mentioned in the docs。因此,创建一个自定义表单,添加您想要的额外字段和内联:
class ImageInline(admin.TabularInline):
model = Image
form = MyCustomForm
答案 1 :(得分:0)
8年后,接受的答案将无效。
例如,在MyInlineForm
的以下设置中,在Django-2.2.3
中呈现自定义表单字段:
class MyInlineAdmin(admin.StackedInline):
model = MyInlineModel
form = MyInlineForm
@admin.register(MyModelAdmin)
class MyModelAdmin(admn.ModelAdmin):
inlines = (MyInlineAdmin,)
受@santhoshnsscoe的启发,可以通过覆盖ModelFormMetaclass.__new__
来实现:
解决方案1:
from django.forms.models import ModelFormMetaclass
class MyModelFormMetaclass(ModelFormMetaclass):
def __new__(cls, name, bases, attrs):
for field in ['test_1', 'test_2', 'test_3']:
attrs[field] = forms.CharField(max_length=30)
return super().__new__(cls, name, bases, attrs)
class MyInlinelForm(forms.ModelForm, metaclass=MyModelFormMetaclass):
class Meta:
model = MyInlineModel
fields = '__all__'
查看相关代码,ModelFormMetaclass
继承自DeclarativeFieldsMetaclass
,其中attrs
传递给以下形式的declared_fields
:
for key, value in list(attrs.items()):
if isinstance(value, Field):
current_fields.append((key, value))
attrs.pop(key)
attrs['declared_fields'] = OrderedDict(current_fields)
基于此观察,并遵循ModelAdmin.get_formsets_with_inlines
的相关文档
我尝试使用declared_fields
的方法丰富ModelAdmin
,它也有效:
解决方案2:
class MyInlineForm(forms.ModelForm):
class Meta:
model = MyInlineModel
fields = '__all__'
class MyInlineAdmin(admin.StackedInline):
model = MyInlineModel
form = MyInlineForm
@admin.register(MyModelAdmin)
class MyModelAdmin(admn.ModelAdmin):
inlines = (MyInlineAdmin,)
def get_formsets_with_inlines(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
if isinstance(inline, MyInlineAdmn):
for field in ['test_1', 'test_2', 'test_3']:
inline.form.declared_fields[field] = forms.CharField(max_length=30)
yield inline.get_formset(request, obj), inline
答案 2 :(得分:0)
class ReactionInline(admin.StackedInline):
model = Reaction
def formfield_for_dbfield(self, db_field, request, **kwargs):
if db_field.name == "reaction":
from fb_post.constants.enums import Reactions
select_choices = [('None', None)] + Reactions.get_list_of_tuples()
kwargs['widget'] = forms.Select(choices=select_choices) # the other case for ModelAdmin "kwargs['widget'].choices = select_choices" this would work
return super(ReactionInline, self).formfield_for_dbfield(db_field, request, **kwargs)
用于在管理面板上为应用程序模型的枚举字段添加下拉菜单功能(例如,Reaction),用于扩展StackedInline或TabularInline类的类;这会工作。另一种解决方案,扩展ModelAdmin的类的解决方案,也在评论
中给出