Django 通用外键过滤(v1.5 和 v1.6 之间的差异)

标签 django generic-foreign-key generic-relations

我有以下概念模型:

class GenericAbstractBase(models.Model):
    name = models.CharField(max_length=255)
    staff = generic.GenericRelation(
        "Staff",
        content_type_field="content_type",
        object_id_field="object_id",
    )

    class Meta:
        abstract = True


class GenericModelA(GenericAbstractBase):
    extra_a = models.CharField(max_length=255)


class GenericModelB(GenericAbstractBase):
    extra_b = models.CharField(max_lenth=10)


class Staff(models.Model):

    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    active = models.CharField(max_length=10, choices = ACTIVE_CHOICES)

    limit = models.Q(app_label='staff', model='genericmodela') | models.Q(app_label='staff', model='genericmodelb')
    content_type = models.ForeignKey(ContentType, limit_choices_to=limit)
    object_id = models.PositiveIntegerField()
    generic_object = generic.GenericForeignKey("content_type", "object_id")

在 Django v1.4 和 Django v1.5 中,以下查询工作正常:

>>> ctype = ContentType.objects.get_for_model(GenericModelA)
>>> Staff.objects.filter(
        content_type=ctype,
        genericmodela__name__icontains="a"
    )
>>> [<Staff: Abbott, Kaylee>, <Staff: Adams, Kay>, ... ]

和它产生的 SQL (sqlite) 看起来像:

SELECT 
    "staff_staff"."id", "staff_staff"."first_name","staff_staff"."last_name",
"staff_staff"."active","staff_staff"."content_type_id" ,"staff_staff"."object_id"
FROM "staff_staff"
INNER JOIN "staff_staff" T2 ON ("staff_staff"."id" = T2."id")
INNER JOIN "staff_genericmodela" ON (T2."object_id" = "staff_genericmodela"."id")
WHERE (
"staff_genericmodela"."name" LIKE % a % ESCAPE \ '\\\'
AND "staff_staff"."content_type_id" = 11
)

但是在 Django 1.6 中,查询失败并出现 FieldError:
FieldError: Cannot resolve keyword 'genericmodela' into field. Choices are: active, content_type, department, first_name, id, last_name, object_id, position

以下声明in the release notes可能是相关的:

Django 1.6 contains many changes to the ORM. These changes fall mostly in three categories:

  1. Bug fixes (e.g. proper join clauses for generic relations, query combining, join promotion, and join trimming fixes)


我的问题是,Django 1.6 中的哪些更改导致此中断?我是否坚持使用 extra或者在 Python 中进行这种类型的过滤?

最佳答案

我找到了一些 interesting information here .

作为一种解决方法,您可以执行以下操作:

ctype = ContentType.objects.get_for_model(GenericModelA)

pk_list = Staff.objects.filter(
    content_type=ctype
).values_list('object_id', flat=True)

GenericModelA.objects.filter(pk__in=pk_list, name__icontains="a")

关于Django 通用外键过滤(v1.5 和 v1.6 之间的差异),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22200791/

相关文章:

模型 Mixin 中的 Django GenericRelation

Django 删除一个 GenericForeignKey

python - 扩展我的搜索功能

python - sqlalchemy 通用外键(就像在 django ORM 中一样)

python - 当用户有权限时,在管理员中获取 "Permission denied"页面

python - update_or_create 的 Django GenericRelation

python - 如何在 Django 中遍历一个 GenericForeignKey?

python - Django GenericRelated 字段条件查询引发 'GenericRelation' 对象没有属性 'field'

python - manage.py startapp从Docker内部创建只读文件

构建 "News Feed"/ "Status update"/ "Activity Stream"的 Django 方式