@lai 在 Django 2.1.2 中,我不得不将第一个 if 语句中的代码从 formfield.choice_cache = cache[db_field.name] 更改为 formfield.choices = cache[db_field.name],就像 jnns 的答案一样。在 Django 版本 2.1.2 中,如果您从 admin.TabularInline 继承,您可以直接覆盖方法 formfield_for_foreignkey(self, db_field, request, **kwargs) 而无需使用 mixin。所以代码可能是这样的:
class MyInline(admin.TabularInline):
model = MyModel
formset = MyModelInlineFormset
extra = 3
def formfield_for_foreignkey(self, db_field, request, **kwargs):
formfield = super().formfield_for_foreignkey(db_field, request, **kwargs)
cache = getattr(request, 'db_field_cache', {})
formfield.cache_choices = True
if db_field.name in cache:
formfield.choices = cache[db_field.name]
else:
formfield.choice_cache = [
formfield.choices.choice(obj) for obj in formfield.choices.queryset.all()
]
request.db_field_cache = cache
request.db_field_cache[db_field.name] = formfield.choices
return formfield
在我的情况下,我还必须覆盖 get_queryset 才能从 select_related 中受益,如下所示:
class MyInline(admin.TabularInline):
model = MyModel
formset = MyModelInlineFormset
extra = 3
def formfield_for_foreignkey(self, db_field, request, **kwargs):
formfield = super().formfield_for_foreignkey(db_field, request, **kwargs)
cache = getattr(request, 'db_field_cache', {})
formfield.cache_choices = True
if db_field.name in cache:
formfield.choices = cache[db_field.name]
else:
formfield.choice_cache = [
formfield.choices.choice(obj) for obj in formfield.choices.queryset.all()
]
request.db_field_cache = cache
request.db_field_cache[db_field.name] = formfield.choices
return formfield
def get_queryset(self, request):
return super().get_queryset(request).select_related('my_field')