我有两个模型,'产品'和'范围',由多个到多个字段链接。 'Product'类在我没写的应用程序中,因此无法修改(我可以为它编辑modeladmin)。我希望在管理员中可以编辑“范围”和“产品”,我希望使用FilteredSelectMultiple,而不是内联管理员。
简化的'models.py':
class Product(models.Model):
name = models.CharField(max_length=64)
#etc...
#I can't modify this class
class Range(models.Model):
name = models.CharField(max_length=32)
products = models.ManyToManyField(Product, related_name='ranges')
和admin.py:
class ProductAdmin(admin.ModelAdmin):
# What do I put here to get a multi-select box for ranges?
# Preferrably with one of those 'add' buttons to popup a window
# to add ranges.
如果我可以修改产品,我可以使用现有的直通表在其上放置一个ManyToManyField,这样可以正常工作,但正如我所说的那样我不能(或者不会因为它会使外部应用程序的升级真实疼痛)。
提前感谢您的帮助! (PS我希望在这里很容易看到为什么我不想使用内联管理表单 - 这会使UI变得不必要地复杂化。)
答案 0 :(得分:2)
对不起它可能有点晚了,但谷歌搜索的任何人都可以从这个答案中受益。这不是那么容易,但它是可行的。您必须构建自己的表单(如果需要,可以从现有表单下载),然后手动加载和保存项目。
from django import forms
from django.contrib import admin
class ProductForm(forms.ModelForm):
# <- your own fields declaration
ranges = forms.ModelMultipleChoiceField(
label='Ranges',
queryset=Range.objects.all(),
required=False,
widget=admin.widgets.FilteredSelectMultiple("ranges", is_stacked=False))
class Meta:
model = Product
class MyProductAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# Save first to obtain id
super(MyProductAdmin, self).save_model(request, obj, form, change)
# Clean and re-add related objects
obj.range_set.clear()
for range in form.cleaned_data['ranges']:
obj.range_set.add(range)
def get_form(self, request, obj=None, **kwargs):
if obj:
ProductForm.base_fields['ranges'].initial = [o.pk for o in obj.range_set.all()]
else:
ProductForm.base_fields['ranges'].initial = []
return ProductForm
# unregister and register again
admin.site.unregister(Product)
admin.site.register(Product, MyProductAdmin)