解决Django Admin外键搜索报错:related Field has invalid lookup: icontains
本文详解在Django Admin中配置外键搜索时遇到的“related Field has invalid lookup: icontains”错误原因及解决方案。通过明确指定外键字段的双下划线查询语法(如book__name)解决搜索失效问题,并补充Python 2.7与3.x版本中__unicode__与__str__方法的兼容处理技巧,确保后台管理界面显示正确。
环境版本与报错现象
运行环境为python 2.7.11
使用的框架版本为django 1.8.4
遇到的报错信息为:related Field has invalid lookup: icontains
外键搜索配置原理
起初误以为Django在处理外键搜索时会自动调用str()方法并将结果用于搜索,但实际并非如此。若要在搜索域中包含外键,必须显式指定具体的字段路径。
以下方案经网络查阅并测试可用,具体配置如下:
代码实现示例
模型定义文件models.py
# coding:utf8
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=255)
title = models.CharField(max_length=255)
price = models.IntegerField()
...
class Category(models.Model):
CATEGORY_CHOICES = (
('00', 'English'),
('01', 'Computer'),
)
book = models.ForeignKey(Book)
category = models.CharField(max_length=255, choices=CATEGORY_CHOICES)
remark = models.CharField(max_length=255)
...
后台管理配置admin.py(以Category模型为例)
# coding: utf8
from django.contrib import admin
from django import forms
from .models import Category
class CategoryAdmin(admin.ModelAdmin):
search_fileds = ('book__name', 'book__title', 'book__price', 'category') # 设置搜索栏范围,如果有外键,要注明外键的哪个字段,双下划线
list_display = ('book', 'category') # 在页面上显示的字段,若不设置则显示 models.py 中 __unicode__(self) 中所返回的值
list_display_links = ('category') # 设置页面上哪个字段可单击进入详细页面
fields = ('category', 'book') # 设置添加/修改详细信息时,哪些字段显示,在这里 remark 字段将不显示
admin.site.register(Category, CategoryAdmin)
关键说明
在Django Admin系统中配置搜索功能时,若未正确指定外键字段,常会触发“related Field has invalid lookup: icontains”错误。其核心原因在于外键查询必须明确指向目标表的具体字段,而非仅引用外键对象本身。
外键字段在搜索配置中不能仅作为模型引用存在,而必须指向另一个表中明确的字段名。
因此,正确的写法是指定特定字段,格式为“本表外键字段__外键所在表需查询字段”,例如使用双下划线连接。
外键显示异常与版本兼容处理
补充知识:Django Model中使用外键时,页面显示为xxx_object的解决方法
在Django中定义A和B两个模型,其中B包含指向A的外键。
class A:
name=models.CharField(max_length=15)
def __unicode__(self):
return self.name
class B:
name=models.CharField(max_length=15)
f=models.ForeignKey(A,on_delete=models.DO_NOTHING)
def __unicode__(self):
return self.name
注意:测试环境使用python2.7时操作正常,但部署至云服务器后,后台管理系统中B模型的f字段显示为A_Object,未能正确显示A模型中name属性的值。
排查发现,云服务器使用的是python3.6,此时需要将__unicode__()方法替换为__str__()方法以符合Python 3的规范。
class A:
name=models.CharField(max_length=15)
def __str__(self):
return self.name
class B:
name=models.CharField(max_length=15)
f=models.ForeignKey(A,on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
若需保持Python 2.x与3.x的良好兼容,可使用@python_2_unicode_compatible装饰器,使代码在Python 3中也能像处理Unicode字符一样正确处理字符串。
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class A:
name=models.CharField(max_length=15)
def __str__(self):
return self.name
@python_2_unicode_compatible
class B:
name=models.CharField(max_length=15)
f=models.ForeignKey(A,on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
以上内容总结了Django Admin中外键搜索配置及版本兼容性的处理方法,供开发者参考。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









