解决Django Admin外键搜索报错:related Field has invalid lookup: icontains

晚来风
晚来风
发布时间:2026-10-13 | 3人浏览过
原创

本文详解在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中外键搜索配置及版本兼容性的处理方法,供开发者参考。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表