我需要将包含我网站上模型视图链接的字段添加到django管理视图中。
当我向list_display
添加字段名称并定义用于呈现此URL的方法时:
class SetAdmin(admin.ModelAdmin):
list_display = ['many other fields', 'show_set_url']
def show_set_url(self, obj):
return '<a href="#">Set</a>' # render depends on other fields
它显示在django admin中的Sets列表中,但不是以模型形式显示。 如何修复此问题并在django admin中添加指向“设置表单”的链接?
我也试过为这个模型创建自定义表单:
from core.models import Set
from django import forms
class SetAdminForm(forms.Form):
class Meta:
model = Set
def __init__(self, *args, **kwargs):
super(SetAdminForm, self).__init__(*args, **kwargs)
self.fields['foo'] = forms.IntegerField(label=u"Link")
但现在形式上有明显效果。
答案 0 :(得分:6)
您可以通过覆盖ModelAdmin
来完成您尝试的操作,但您还需要覆盖ModelAdmin.get_fieldsets
。 This回答可能会帮到你。链接中的OP也存在类似的问题。
修改:如果您不想要可编辑字段,可以尝试覆盖ModelAdmin.get_readonly_fields
。同时检查here是否有更多要覆盖的属性。
答案 1 :(得分:2)
您可以使用表单元类创建动态字段和字段集。示例代码如下。根据您的要求添加循环逻辑。
class CustomAdminFormMetaClass(ModelFormMetaclass):
"""
Metaclass for custom admin form with dynamic field
"""
def __new__(cls, name, bases, attrs):
for field in myloop: #add logic to get the fields
attrs[field] = forms.CharField(max_length=30) #add logic to the form field
return super(CustomAdminFormMetaClass, cls).__new__(cls, name, bases, attrs)
class CustomAdminForm(six.with_metaclass(CustomAdminFormMetaClass, forms.ModelForm)):
"""
Custom admin form
"""
class Meta:
model = ModelName
fields = "__all__"
class CustomAdmin(admin.ModelAdmin):
"""
Custom admin
"""
fieldsets = None
form = CustomAdminForm
def get_fieldsets(self, request, obj=None):
"""
Different fieldset for the admin form
"""
self.fieldsets = self.dynamic_fieldset(). #add logic to add the dynamic fieldset with fields
return super(CustomAdmin, self).get_fieldsets(request, obj)
def dynamic_fieldset(self):
"""
get the dynamic field sets
"""
fieldsets = []
for group in get_field_set_groups: #logic to get the field set group
fields = []
for field in get_group_fields: #logic to get the group fields
fields.append(field)
fieldset_values = {"fields": tuple(fields), "classes": ['collapse']}
fieldsets.append((group, fieldset_values))
fieldsets = tuple(fieldsets)
return fieldsets
答案 2 :(得分:1)
我在Django 1.9中为内联模型解决了所有这些问题。
这是一个为我完成动态字段的代码片段。在这个例子中,我假设你已经有一个名为ProductVariant的模态,它包含一个名为Product的模型的外键关系:
class ProductVariantForm(forms.ModelForm):
pass
class ProductVariantInline(admin.TabularInline):
model = ProductVariant
extra = 0
def get_formset(self, request, obj=None, **kwargs):
types = ( (0, 'Dogs'), (1, 'Cats'))
#Break this line appart to add your own dict of form fields.
#Also a handy not is you have an instance of the parent object in obj
ProductVariantInline.form = type( 'ProductVariantFormAlt', (ProductVariantForm, ), { 'fancy_select': forms.ChoiceField(label="Animals",choices=types)})
formset = super( ProductVariantInline, self).get_formset( request, obj, **kwargs)
return formset
class ProductAdmin(admin.ModelAdmin):
inlines = (ProductVariantInline, )
我的具体用例是ProductVariant有多对多的关系,只能根据条目的业务逻辑分组进行有限的选择。因此我需要在内联中自定义动态字段。
答案 3 :(得分:0)
您必须将其添加到readonly_fields
列表。
class SetAdmin(admin.ModelAdmin):
list_display = ['many other fields', 'show_set_url']
readonly_fields = ['show_set_url']
def show_set_url(self, obj):
return '<a href="#">Set</a>' # render depends on other fields
答案 4 :(得分:0)
对@santhoshnsscoe表示敬意,在Django-2.2.3
中用于实现此目标的最少代码如下:
from django.forms.models import BaseInlineFormSet, 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 MyModelForm(forms.ModelForm, metaclass=MyModelFormMetaclass):
class Meta:
model = MyModel
fields = '__all__'
class MyModelAdmin(admin.modelAdmin):
form = MyModelForm