我有一个链接到相关模型的模型,该模型是Django MPTT树模型,我希望能够在管理控制台中使用Django MPTT树过滤第一个模型。
class Tenders(models.Model):
...
sector=models.ForeignKey(Sector, to_field='sectorId', null=True, blank=True,on_delete=models.CASCADE)
...
class Sector(MPTTModel):
name = models.CharField(max_length = 255)
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True,related_name='children')
sectorId = models.IntegerField(default=0,null=True,unique=True)
在Django管理员中,我想为Tenders模型设置过滤器,以使Django-MPTT树成为过滤器。
我尝试使用以下内容:
class adminTenders(admin.ModelAdmin):
def linkTo(self,obj):
return mark_safe("""<a href='{}' target="_blank" >Tender Link</a>""".format(obj.tenderLink))
linkTo.short_description=''
list_display=(
'title',
'linkTo',
'sector',
'region',
'repository',
'id',
)
list_filter=(
('sector', TreeRelatedFieldListFilter),
)
admin.site.register(Tenders,adminTenders)
但是,尝试运行此错误时出现以下错误,我无法弄清:
File "py36/lib/python3.6/site-packages/mptt/admin.py", line 314, in field_choices
mptt_level_indent * levels_dict[pk])
KeyError: 0
任何帮助将不胜感激。
编辑1:我认为我将问题隔离到以下事实:我的“行业招标书”中的外键使用to_field='sectorId
而不是默认链接到{{1} }列。这样做是为了向后兼容我所坚持的旧数据库方案。
答案 0 :(得分:0)
因此,事实证明,这是field_choices
类中TreeRelatedFieldListFilter
函数的django-mptt代码中的错误。
要解决此问题,我必须继承该函数,然后使用该函数使用我定义的to_field
。
这是自定义代码:
class TreeRelatedForSectors(TreeRelatedFieldListFilter):
# Modified from django-mptt code to fix to_field problem
def field_choices(self, field, request, model_admin):
mptt_level_indent = getattr(model_admin, 'mptt_level_indent', self.mptt_level_indent)
language_bidi = get_language_bidi()
initial_choices = field.get_choices(include_blank=False)
pks = [pk for pk, val in initial_choices]
models = field.related_model._default_manager.filter(sectorId__in=pks)
levels_dict = {model.sectorId: getattr(model, model._mptt_meta.level_attr) for model in models}
choices = []
for pk, val in initial_choices:
padding_style = ' style="padding-%s:%spx"' % (
'right' if language_bidi else 'left',
mptt_level_indent * levels_dict[pk])
choices.append((pk, val, mark_safe(padding_style)))
return choices