2009-07-16 6 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 '} 

を与えるが、=はそれであることを意味するように私には思えます1つのオブジェクト。 djangoが実際に行っているクエリは、オブジェクトがの場合はどこでもの達成リストに戻ります。

これは正しく設定されていますか?非常に直感的ですか、何か間違っていますか?

答えて

1

2番目のケースでは、オブジェクトを比較しています。 Django documentationから、オブジェクトを比較するには、==演算子を使用する必要があります。

query section of the manualで説明されているように、ach.alias_set.objects.count()を使用しないのはなぜですか?

+0

クエリは同等ですか?それはお勧めの方法ですか? (私はdjango初心者です) –

+0

はい、そうです。私はDjangoのドキュメンテーションへのリンクを追加しました。 –

+0

もう1つの理由は、外部キーを候補キーフィールド(データベース内でユニークなもの)に設定することを永久に排除し、これは複数列の主キーを実装することを排除し、DjangoのORMは大規模ではない - トリビアルスキーマ。 – zxq9

2

私はこのようにして実装する意思決定がなされた理由に答えることはできませんが、Pythonの哲学に従い、明示的かつ暗示的に指定する必要があります。

__containsが参照するフィールドが必要なためです。あなたが渡したビットは、オブジェクト全体への参照でした。

関連する問題