3

我有一个包含一些对象的查询集。根据某些情况或其他情况,我现在想排除所有没有特定标签的对象(_tags 是我模型上 TagField 的名称):

self.queryset=self.queryset.exclude(_tags__id__in=avoid)

但这只会给我留下一个错误:

Caught FieldError while rendering:
Join on field '_tags' not permitted.
Did you misspell 'id' for the lookup type?

因为我很确定我没有拼错“id”,所以我做了一些关于如何使用标记来处理这样的事情的搜索。在文档中有很多关于自定义管理器的内容,但不知何故我无法理解如何使用它们来获得我想要的东西。

编辑:

将上面的代码更正为

self.queryset=self.queryset.exclude(_tags__in=avoid)

其中避免是整数列表。这给我留下了一个问题,即 django-tagging 的 TagField 只是一个特殊的 CharField(或 TextField?)。当然,如果我只是根据整数列表查询它,它不会整理出任何东西。我可以尝试以这样的方式解决这个问题:

for tag in avoid:
    self.queryset=self.queryset.exclude(_tags__contains=tag.name)

这不仅丑陋,而且还给我留下了由多个单词组成的标签或匹配其他标签的部分的问题。

不知何故,我怀疑这可以由了解 django-tagging 如何工作的人以更漂亮的方式解决。

4

3 回答 3

3

你的模型是如何定义的?_tags 是 ForeignKey 字段吗?

如果不删除 __id 部分

self.queryset=self.queryset.exclude(_tags__in=avoid)
于 2012-03-23T13:25:57.507 回答
2

不幸的是,不,没有更漂亮的方法。事实上,实际的解决方案更丑陋,但是当所有标签都存储在一个文本字段中时,就没有其他办法了:

from django.db.models import Q

startswith_tag = Q(_tags__startswith=tag.name+' ')
contains_tag = Q(_tags__contains=' '+tag.name+' ')
endswith_tag = Q(_tags__endswith=' '+tag.name)
self.queryset=self.queryset.exclude(startswith_tag | contains_tag | endswith_tag)

上面的代码假定标签用空格分隔。如果不是,您将不得不修改代码以匹配它们的分隔方式。这个想法是您使用分隔符作为搜索的一部分,以确保它是实际标记,而不仅仅是另一个标记的一部分。

如果您不想这样做,我建议切换到另一个不会将它们全部转储到单个文本字段中的标签系统,例如django-taggit

于 2012-03-23T14:57:57.840 回答
0

如对 Chris 回答的评论中所述,django-tagging 在访问model._tag. 最后,除了进行查询并整理出包含某个标签的循环之外,我没有其他解决方案:

itemlist = list(queryset)
avoid = some_list_of_tag_ids            
# search for loops that have NONE of the avoid tags
for item in itemlist:
    #    has tags   and [ if a tag.id in avoid this list has an element]
    if (item.tags)  and [tag for tag in item.tags if tag.id in avoid]:
        # remove the item from the list
        itemlist.remove(item)

为了完成这个模型,它看起来像这样:

class Item(models.Model):

    _tags = TagField(blank=True,null=True)

    def _get_tags(self):
        return Tag.objects.get_for_object(self)
    def _set_tags(self, tags):
        Tag.objects.update_tags(tags)

    tags = property(_get_tags, _set_tags)

尽管我尝试了很长时间,但我发现无法将针对标记标签的查询链接到对象的查询链中。对于这个项目,我坚持使用标签,但这是一个真正的缺点......

于 2012-03-24T12:25:26.710 回答