嗨,我试图为django编写一个标记系统,但今天在filter或q对象(django.db.models.q)中遇到了一个奇怪的行为。
我编写了一个函数,将搜索字符串转换为q对象。下一步是用这些查询过滤taggedobject。但不幸的是我有一个奇怪的行为。
只搜索一个标记元素:
当我搜索时
(id=20)
= & gt;
Q: (AND: ('tags__tag__id', 20))
它返回两个带标记的对象,id为1127和132
当我搜索时
(id=4)
= & gt;
Q: (AND: ('tags__tag__id', 4))
它还返回两个对象,但这次是1180和1127
以下是重新计算SQL查询:
SELECT "django_content_type"."id", "django_content_type"."name", "django_content_type"."app_label", "django_content_type"."model"
FROM "django_content_type"
WHERE ("django_content_type"."model" = slogan AND "django_content_type"."app_label" = slogans )
ORDER BY "django_content_type"."name" ASC
SELECT "slogans_slogan"."id", "slogans_slogan"."headline", "slogans_slogan"."text", "slogans_slogan"."author"
FROM "slogans_slogan"
INNER JOIN "htags_objecttagbridge" ON ("slogans_slogan"."id" = "htags_objecttagbridge"."object_id")
WHERE ("htags_objecttagbridge"."tag_id" = 4 AND "htags_objecttagbridge"."content_type_id" = 9 )
LIMIT 21
搜索两个带有“或”连词的标记:
直到这里一切都很好,但是当我做一个更复杂的查询时
(id=4) or (id=20)
= & gt;
Q: (OR: ('tags__tag__id', 4), ('tags__tag__id', 20))
然后返回4(!)对象1180、1127、1127、132
和SQL:
SELECT "slogans_slogan"."id", "slogans_slogan"."headline", "slogans_slogan"."text", "slogans_slogan"."author"
FROM "slogans_slogan"
INNER JOIN "htags_objecttagbridge" ON ("slogans_slogan"."id" = "htags_objecttagbridge"."object_id")
WHERE ((("htags_objecttagbridge"."tag_id" = 4 AND "htags_objecttagbridge"."content_type_id" = 9 ) OR "htags_objecttagbridge"."tag_id" = 20 ) AND "htags_objecttagbridge"."content_type_id" = 9 )
LIMIT 21
但是id为1127的对象返回了两次,但这不是我想要的行为。我必须接受它吗?我能不能做点不同的事。q对象的表示对我来说很好。
搜索两个标记“and”连词
但最糟糕的是,当我寻找
(id=20) and (id=4)
= & gt;
Q: (AND: ('tags__tag__id', 20), ('tags__tag__id', 4))
然后它根本不返回任何对象。但是为什么呢?表示应该是OK的,ID为1127的对象由两者标记。我错过了什么?
下面是SQL:
SELECT "slogans_slogan"."id", "slogans_slogan"."headline", "slogans_slogan"."text", "slogans_slogan"."author"
FROM "slogans_slogan"
INNER JOIN "htags_objecttagbridge" ON ("slogans_slogan"."id" = "htags_objecttagbridge"."object_id")
WHERE ("htags_objecttagbridge"."tag_id" = 4 AND "htags_objecttagbridge"."content_type_id" = 9 AND "htags_objecttagbridge"."tag_id" = 20 )
LIMIT 21
[编辑]:
我现在意识到,这个sql语句是错误的。至少不是我想要的,因为在这里,一个objecttagbridge有id 4,同时还有id 20。但在我的情况下这是两个不同的
以下是课程的相关部分:
class TaggedObject(models.Model):
"""
class that represent a tagged object
"""
tags = generic.GenericRelation('ObjectTagBridge',
blank=True, null=True)
class ObjectTagBridge(models.Model):
"""
Help to connect a generic object to a Tag.
"""
# pylint: disable-msg=W0232,R0903
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
tag = models.ForeignKey('Tag')
class Tag(models.Model):
...
谢谢你的帮助