2009-07-16 3 views
3

나는이 작동Django : 외래 키 조회가 자동으로 pk를 사용하지 않는 이유는 무엇입니까?

class Achievement(MyBaseModel): 
    pass 

class Alias(MyBaseModel): 
    achievements = models.ManyToManyField('Achievement') 

>>> ach = Achievement.objects.all()[1] 

있습니다

>>> Alias.objects.all().filter(achievements__pk__contains=ach.pk).count() 
77L 

을하지만 그렇지 않은 :

>>> Alias.objects.all().filter(achievements__contains=ach).count() 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/var/home/ptarjan/django/mysite/django/db/models/query.py", line 489, in filter 
    return self._filter_or_exclude(False, *args, **kwargs) 
    File "/var/home/ptarjan/django/mysite/django/db/models/query.py", line 507, in _filter_or_exclude 
    clone.query.add_q(Q(*args, **kwargs)) 
    File "/var/home/ptarjan/django/mysite/django/db/models/sql/query.py", line 1258, in add_q 
    can_reuse=used_aliases) 
    File "/var/home/ptarjan/django/mysite/django/db/models/sql/query.py", line 1201, in add_filter 
    self.where.add((alias, col, field, lookup_type, value), connector) 
    File "/var/home/ptarjan/django/mysite/django/db/models/sql/where.py", line 48, in add 
    params = field.get_db_prep_lookup(lookup_type, value) 
    File "/var/home/ptarjan/django/mysite/django/db/models/fields/related.py", line 156, in get_db_prep_lookup 
    raise TypeError, "Related Field has invalid lookup: %s" % lookup_type 
TypeError: Related Field has invalid lookup: contains 

이유는 무엇입니까? (Django 1.0.2)

쿼리 로그를 보면 예상치 못한 일을하고 있습니다! 즉, 쿼리는 굴복 :

>>> connection.queries[-1] 
{'time': '0.027', 'sql': u'SELECT COUNT(*) FROM `yourock_alias` INNER JOIN `yourock_achiever` ON (`yourock_alias`.`id` = `yourock_achiever`.`alias_id`) WHERE `yourock_achiever`.`achievement_id` LIKE BINARY %j0xvw9% '} 

그러나이

>>> Alias.objects.all().filter(achievements=ach).count() 
77L 

을하는 것은 내가 원하는 무엇을이 쿼리

>>> connection.queries[-1] 
{'time': '0.023', 'sql': u'SELECT COUNT(*) FROM `yourock_alias` INNER JOIN `yourock_achiever` ON (`yourock_alias`.`id` = `yourock_achiever`.`alias_id`) WHERE `yourock_achiever`.`achievement_id` = j0xvw9 '} 

를 제공하지만, = 것을 의미 나에게 보인다 하나의 대상. django가 수행중인 쿼리는 업적 목록에있는 객체가 인 경우이면 반환됩니다.

올바르게 설정 되었습니까? 매우 직관력이 있습니까? 아니면 잘못된 것이 있습니까?

답변

1

두 번째 경우에는 개체를 비교하고 있습니다. 그리고 Django documentation에서 개체를 비교하려면 == 연산자를 사용해야합니다.

위에 : query section of the manual에 설명 된대로 ach.alias_set.objects.count()을 사용하지 않으시겠습니까?

+0

검색어와 일치합니까? 그것은 권장 방법입니까? (난 장고 초보자) –

+0

예, 그렇습니다. Django 문서에 대한 링크를 추가했습니다. "backward"관계를 따르는 방법입니다. –

+0

또 다른 이유는 영원히 외래 키를 후보 키 필드 (db에서 고유 한 키)로 설정하는 것을 배제하고 이는 다중 열 기본 키를 구현하지 못하게하고 따라서 Django의 ORM이 대규모 비대칭 - 전용 스키마. – zxq9

2

이 방법으로 구현하기로 결정한 이유는 무엇인지는 모르겠지만 대부분은 파이썬 철학에 따라 명시 적으로 명시해야 함을 의미하지는 않습니다.

__contains에서 필드를 참조해야하기 때문에 작동하지 않는 이유가 있습니다. 당신이 전달한 비트는 전체 객체에 대한 참조였습니다.

관련 문제