通用外键字段上的搜索字段

时间:2019-04-17 11:13:22

标签: django django-models django-admin

我正在尝试将搜索字段添加到Django管理模型CreditsAdmin中,这将允许我搜索相关客户对象的电子邮件。 Customer对象对许多不同类型的对象都有通用的外键,所有对象都有电子邮件。

我已经尝试在customer_email对象上定义函数Customer并将其用作搜索字段,但这会产生错误Related Field got invalid lookup: customer_email

class Customer(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    @property
    def customer_email(self):
        return str(self.content_object.email)


class Credits(models.Model):
    credits_remaining = models.IntegerField()
    current_period_start = models.DateTimeField()
    current_period_end = models.DateTimeField()
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE)


class CreditsAdmin(admin.ModelAdmin):
    list_display = (
        'current_period_start',
        'current_period_end',
        'customer_name',
        'credits_remaining',
    )

    search_fields = ('customer__customer_email',)

我希望能够通过Customer界面在CreditsAdmin模型上搜索相关通用对象的电子邮件。特别地,与客户对象相关的content_type之一是django的auth.User模型,但还有其他模型。

1 个答案:

答案 0 :(得分:0)

您不能在search_fields中使用属性,因为它会在数据库级别查找列。

GenericRelation可能是一种解决方案。您可以在相关(按内容类型)模型中创建字段。例如:

class CntObject(models.Model):
    customers = GenericRelation(Customer, related_query_name='cnt_objects')

在“积分”管理面板中:

class CreditsAdmin(admin.ModelAdmin):
list_display = (
    'current_period_start',
    'current_period_end',
    'customer_name',
    'credits_remaining',
)

search_fields = ('customer__cnt_objects__email',)

此答案并非是最好的选择。您必须确保所有相关的content_objects都将包含电子邮件字段。可能是性能问题,没有测试。

其他解决方案可能是您在管理类中自定义的get_search_results方法。