试图让 optgroup 标签出现在 Django 管理内联中
Trying to get optgroup tag to appear in Django admin inline
以下是目前为止我认为可行的方法,但我收到了这个错误:
Template error
In template /usr/lib/python2.7/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html, error at line 50
Caught TypeError while rendering: render_option() takes exactly 4 arguments (23 given)
40 {% endspaceless %}
41 </td>
42 {% for fieldset in inline_admin_form %}
43 {% for line in fieldset %}
44 {% for field in line %}
45 <td class="{{ field.field.name }}">
46 {% if field.is_readonly %}
47 <p>{{ field.contents }}</p>
48 {% else %}
49 {{ field.field.errors.as_ul }}
50 {{ field.field }} <--- error here
代码在admin.py
def get_construct_choices():
construct_request_choices = Construct.objects.all().order_by('family','promotor','additional_mutation')
construct_request_choices = itertools.groupby(construct_request_choices, key=lambda x:str(x.family))
choices = []
for family, group in construct_request_choices:
choices.append((family, [str(val) for val in group]))
print choices
return choices
class ConstructRequestCustomForm(forms.ModelForm):
class Meta:
model = ConstructRequest
construct = forms.ChoiceField(choices=get_construct_choices())
class ConstructRequestInline(admin.TabularInline):
model = ConstructRequest
form = ConstructRequestCustomForm
extra = 1
class RequestAdmin(make_DefaultAdminAuditTable(Request)):
inlines = (ConstructRequestInline,)
如果您为 choices
使用命名组,每个组的第二个元素应该是一个可迭代的二元组。文档中的示例是:
CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)
在您的代码中,您正在做
choices.append((family, [str(val) for val in group]))
所以看起来第二个元素是一个字符串列表,而不是一个二元组列表。如果你这样做可能会奏效
choices.append((family, [(str(val), str(val)) for val in group]))
或者如果您希望显示值与数据库中存储的值不同,您可能需要稍微更改它。
最后,因为get_construct_choices
访问数据库,所以最好在表单的__init__
方法中设置选项。否则,选择将在代码加载时加载,但不会更新。
class ConstructRequestCustomForm(forms.ModelForm):
class Meta:
model = ConstructRequest
def __init__(self, *args, **kwargs):
super(ConstructRequestCustomForm, self).__init__(*args, **kwargs)
self.fields['construct'].choices = get_construct_choices()
以下是目前为止我认为可行的方法,但我收到了这个错误:
Template error
In template /usr/lib/python2.7/site-packages/django/contrib/admin/templates/admin/edit_inline/tabular.html, error at line 50
Caught TypeError while rendering: render_option() takes exactly 4 arguments (23 given)
40 {% endspaceless %}
41 </td>
42 {% for fieldset in inline_admin_form %}
43 {% for line in fieldset %}
44 {% for field in line %}
45 <td class="{{ field.field.name }}">
46 {% if field.is_readonly %}
47 <p>{{ field.contents }}</p>
48 {% else %}
49 {{ field.field.errors.as_ul }}
50 {{ field.field }} <--- error here
代码在admin.py
def get_construct_choices():
construct_request_choices = Construct.objects.all().order_by('family','promotor','additional_mutation')
construct_request_choices = itertools.groupby(construct_request_choices, key=lambda x:str(x.family))
choices = []
for family, group in construct_request_choices:
choices.append((family, [str(val) for val in group]))
print choices
return choices
class ConstructRequestCustomForm(forms.ModelForm):
class Meta:
model = ConstructRequest
construct = forms.ChoiceField(choices=get_construct_choices())
class ConstructRequestInline(admin.TabularInline):
model = ConstructRequest
form = ConstructRequestCustomForm
extra = 1
class RequestAdmin(make_DefaultAdminAuditTable(Request)):
inlines = (ConstructRequestInline,)
如果您为 choices
使用命名组,每个组的第二个元素应该是一个可迭代的二元组。文档中的示例是:
CHOICES = (
('Audio', (
('vinyl', 'Vinyl'),
('cd', 'CD'),
)
),
('Video', (
('vhs', 'VHS Tape'),
('dvd', 'DVD'),
)
),
('unknown', 'Unknown'),
)
在您的代码中,您正在做
choices.append((family, [str(val) for val in group]))
所以看起来第二个元素是一个字符串列表,而不是一个二元组列表。如果你这样做可能会奏效
choices.append((family, [(str(val), str(val)) for val in group]))
或者如果您希望显示值与数据库中存储的值不同,您可能需要稍微更改它。
最后,因为get_construct_choices
访问数据库,所以最好在表单的__init__
方法中设置选项。否则,选择将在代码加载时加载,但不会更新。
class ConstructRequestCustomForm(forms.ModelForm):
class Meta:
model = ConstructRequest
def __init__(self, *args, **kwargs):
super(ConstructRequestCustomForm, self).__init__(*args, **kwargs)
self.fields['construct'].choices = get_construct_choices()