Django: Why don't external searches automatically use pk?

I have

class Achievement(MyBaseModel):
    pass

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

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

It works:

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

But this is not so:

>>> 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

Why? (Django 1.0.2)

Looking at the query log, he does what I did not expect! This query gave:

>>> 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% '}

But by doing it

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

Gives this request

>>> 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 '}

which is what I wanted, but =it seems to me that he IS one object. The query that django makes is truly returned if the object is anywhere in the achievement list.

Is it configured correctly and just very intuitive, or am I doing something wrong?

+3
source share
2 answers

. Django, , ==.

: ach.alias_set.objects.count(), ?

+1

, , , , Python, .

, , , __contains , . , , .

+2

Source: https://habr.com/ru/post/1712754/


All Articles