在搜索字段中正确使用外键引用,Django admin

Posted

技术标签:

【中文标题】在搜索字段中正确使用外键引用,Django admin【英文标题】:Properly using Foreign Key references in search_fields, Django admin 【发布时间】:2016-05-09 20:41:30 【问题描述】:

我有一个奇怪的难题,我需要在 Django 1.8.4 中在虚拟环境中使用 python 3.4 的帮助。

我在 2 个不同的应用程序中有 2 个模型...如下所示,带有多个外键引用。

库存应用

class InventoryItem(models.Model):
    item_unique_code = models.CharField(max_length=256, blank=False, null=False)
    category = models.CharField(max_length=256, blank=False, null=False,choices=[('RAW','Raw Material'),('FG','Finished Good'),('PKG','Packaging')])
    name = models.CharField(max_length=64, blank=False, null=False)
    supplier = models.CharField(max_length=96, blank=False,null=False)
    approved_by = models.CharField(max_length=64, editable=False)
    date_approved = models.DateTimeField(auto_now_add=True, editable=False)
    comments = models.TextField(blank=True, null=True)

    def __str__(self):
        return "%s | %s | %s" % (self.item_unique_code,self.name,self.supplier)

    class Meta:
        managed = True
        unique_together = (('item_unique_code', 'category', 'name', 'supplier'),)

食谱应用

class RecipeControl(models.Model):
    #recipe_name choice field needs to be a query set of all records containing "FG-Finished Goods"
    recipe_name = models.ForeignKey(items.InventoryItem, related_name='recipe_name', limit_choices_to='category': 'FG')
    customer = models.ForeignKey(customers.CustomerProfile, related_name='customer')
    ingredient = models.ForeignKey(items.InventoryItem, related_name='ingredient')
    min_weight = models.DecimalField(max_digits=16, decimal_places=2, blank=True, null=True)
    max_weight = models.DecimalField(max_digits=16, decimal_places=2, blank=True, null=True)
    active_recipe = models.BooleanField(default=False)
    active_by = models.CharField(max_length=64, editable=False)
    revision = models.IntegerField(default=0)
    last_updated = models.DateTimeField(auto_now_add=True, editable=False)

    def __str__(self):
       return "%s" % (self.recipe_name)

    class Meta:
        managed = True
        unique_together = (('recipe_name', 'customer', 'ingredient'),)

我在我的 Recipe 的管理类中得到了一些奇怪的结果...

from django.contrib import admin
from django.contrib.auth.models import User
from .models import RecipeControl
from Inventory import models

class RecipeView(admin.ModelAdmin):
    def save_model(self, request, obj, form, change): 
        obj.active_by = request.user.username
        obj.save()

    fieldsets = [
        ('Recipe Information',               'fields': ['recipe_name', 'customer']),
        ('Ingredients', 'fields': ['ingredient','min_weight','max_weight','active_recipe']),
        ('Audit Trail', 'fields': ['active_by','revision','last_updated'],'classes':['collaspe']),
    ]

    list_select_related = ['recipe_name','customer','ingredient']
    search_fields = ['recipe_name','customer','ingredient','active_by']
    readonly_fields = ('last_updated','active_by')
    list_display = ['recipe_name','customer','ingredient','min_weight','max_weight','last_updated','active_by', 'active_recipe']

admin.site.register(RecipeControl, RecipeView)

我遇到的问题是,如果我尝试在任何 ForeignKey 字段上进行搜索,Django 会抛出此错误...

Exception Type: TypeError at /admin/Recipe/recipecontrol/
Exception Value: Related Field got invalid lookup: icontains

根据 Django Admin Doc's 和关于 *** 的其他旧问题,它说我应该按照 search_fields = ['inventoryitem__name'] 的方式做一些事情,但我认为这是参考到 FK 在同一个应用程序 model.py 中。 是否有更正确的方法可以从我丢失的其他应用程序中引用/导入其他模型,或者我是否必须使用某种可调用的方法魔术才能正确查找搜索功能?我尝试了多种不同的组合,但似乎没有任何效果。我对 Django 比较陌生,所以我相信这很简单。

【问题讨论】:

【参考方案1】:

您应该使用双下划线符号来搜索相关对象的字段。但是,您应该使用外键字段的名称(例如recipe_name),而不是模型的名称(例如InventoryItem)。外键的模型是否在同一个应用程序中并不重要。例如:

search_fields = ['recipe_name__name']

请注意,如果您要搜索 recipe_name 和成分字段,则需要包括这两个字段,即使它们是同一模型的外键。

search_fields = ['recipe_name__name', 'ingredient__name']

【讨论】:

非常感谢您解决这个问题! Django 文档的详细程度不足以让我得到消息。

以上是关于在搜索字段中正确使用外键引用,Django admin的主要内容,如果未能解决你的问题,请参考以下文章

django如何在 search_fields和list_filter 中包含外键字段

使用 Django,如何添加引用同一个表的外键列? [复制]

django模型中, 外键字段使用to_filed属性 指定到所关联主表的某个字段

Django - 根据模型字段生成 excel 报告

Django为特定外键选择具有重复字段值的行

尝试在 Django 中使用外键列表创建 PostgreSQL 字段