簡體   English   中英

Django - 在管理界面中的內聯表單中添加一個額外的字段

[英]Django - Add an extra field to an inline form in admin interface

假設我在admin.py中有以下內容:

class ImageInline(admin.TabularInline):
    model = Image

class ObjectAdmin(admin.ModelAdmin):
    inlines = [ ImageInline, ]

如何向ImageInline添加一個不是Image模型中的字段的額外字段?

與使用普通 ModelAdmin 的方法相同。 InlineModelAdmin 可以接受表單屬性, 它在 docs 中提到 因此,創建一個自定義表單,在您的內聯中添加您想要的額外字段:

class ImageInline(admin.TabularInline):
   model = Image
   form = MyCustomForm

8年后,接受的答案將不起作用。

例如,在Django-2.2.3的以下設置中呈現MyInlineForm中的自定義表單字段:

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的相關文檔,我嘗試使用ModelAdmin的該方法豐富declared_fields的字段,它也有效:

解決方案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
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)

用於在管理面板上為應用模型的枚舉字段(比如反應)添加下拉菜單功能,用於擴展 StackedInline 或 TabularInline 類的類; 這會奏效。 另一種情況的解決方案,擴展 ModelAdmin 的類也在評論中給出

使用“extra_field”創建“CustomImageForm”類並將其設置為“ImageInline”類,如下所示:

# "admin.py"

from django.contrib import admin
from django import forms
from .models import Image, ObjectAdmin

# Here
class CustomImageForm(forms.ModelForm):
    extra_field = forms.CharField()
    
class ImageInline(admin.TabularInline):
    model = Image
    form = CustomImageForm # Here

@admin.register(ObjectAdmin)
class ObjectAdmin(admin.ModelAdmin):
    inlines = [ImageInline,]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM