2012-03-23 3 views
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) 

에 위의 코드를 수정했습니다. 그리고 그 장고 태그의 TagField 그냥 특수 CharField (또는 TextField?) 문제가 날 나뭇잎. 물론 정수 목록에 대해 쿼리하면 어떤 것을 정렬하지 않습니다.

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

뿐만 아니라 추한뿐만 아니라 여러 단어 또는 다른 태그와 일치하는 부분으로 구성 태그의 문제 나 잎 :이 같은 방법으로이 문제를 해결을 시도 할 수 있습니다.

나는 장고 태깅이 어떻게 작동하는지 이해 한 사람이이 방법을 훨씬 더 예쁘게 해결할 수 있다는 의혹을 가지고 있습니다.

답변

0

Chris의 대답에 대한 설명에서 설명한대로 django-tagging은 model._tag에 액세스 할 때 태그 문자열을 제공하지 않습니다.

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) 

Allthough :

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) 

이의 모델이 같다고 완료하려면 : 결국 내가 쿼리를하고 이후에 특정 태그가 포함 된 루프를 분류하는 것보다 다른 해결책이 없었다 나는 꽤 오랫동안 노력했는데, 객체에 대한 질의 체인에 태그를 태그하는 것에 대한 질의를 체인화하는 방법을 찾지 못했습니다.이 프로젝트의 경우 태그가 붙어 있지만 실제 결점이 있습니다 ...

3

모델은 어떻게 정의되어 있습니까? _tags는 ForeignKey 필드입니까? __id 부분

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

또한 템플릿에서 _tags 필드에 직접 액세스 할 수 없습니다. 밑줄로 시작하는 필드 이름은 허용되지 않습니다. 나는 밑줄로 그 이름을 시작하지 않을 것을 권한다. – Mikael

+0

당신의 빠른 대답에 감사드립니다. 당신은 쿼리 인수에 대해 절대적으로 옳았지 만 그건 내 문제를 해결하지 못합니다. _tags는 모델에 tags라는 속성이 있기 때문에 그대로 호출됩니다. 템플릿에서 훨씬 쉽게 액세스 할 수 있습니다.) – marue

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이라는 단일 텍스트 필드에 모두 덤프하지 않는 다른 태그 시스템으로 전환하는 것이 좋습니다.

+0

감사합니다. 오래전에 taggit으로 전환 했었지만 불행히도 태그 지정을 사용하는 다른 앱을 사용하고 있습니다 ... 그런데 Q는 무엇입니까? 자리 표시 자입니까? – marue

+1

'Q'는 단순히 쿼리 인수를 캡슐화하는 객체입니다. OR 및 비 전통적인 AND를 사용하여 복잡한 쿼리를 허용하기 위해 존재합니다. https : //docs.djangoproject.com/en/dev/topics/db/queries/#complex-lookups-with-q –

+0

한 가지 더. 난 그냥 깨달았다 : 안타깝게도 장고 태그는'model._tags'에 접근 할 때 tagstring을 전달하지 않는다. TagField를 생성하는 것처럼 보이는 것은 모델을 태그 지정 가능으로 등록하는 또 다른 방법 일뿐입니다. 그래서이 솔루션조차도 작동하지 않습니다. – marue