Ich habeDjango: Warum verwenden Fremdschlüsselabfragen nicht automatisch den PK?
class Achievement(MyBaseModel):
pass
class Alias(MyBaseModel):
achievements = models.ManyToManyField('Achievement')
>>> ach = Achievement.objects.all()[1]
Dies funktioniert:
>>> Alias.objects.all().filter(achievements__pk__contains=ach.pk).count()
77L
Aber dies nicht:
>>> 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
Warum? (Django 1.0.2)
Mit Blick auf das Abfrageprotokoll tut es etwas, das ich nicht erwartet habe! Diese Abfrage ergab:
>>> 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% '}
Aber dieses tun
>>> Alias.objects.all().filter(achievements=ach).count()
77L
gibt diese Abfrage
>>> 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 '}
das ist, was ich wollte, aber die =
scheint mir zu verstehen, dass es IS das eine Objekt. Die Abfrage, die django gerade ausführt, wird zurückgegeben, wenn das Objekt irgendwo in der Leistungsliste ist.
Ist das richtig eingerichtet und ist nur sehr kontraintuitiv oder mache ich etwas falsch?
Ist Ihre Anfrage gleichwertig? Ist es der empfohlene Weg? (Ich bin ein Django-Neuling) –
Ja, ist es. Ich habe einen Link zur Django-Dokumentation hinzugefügt, um zu erfahren, wie man einer Beziehung "rückwärts" folgen kann. –
Ein anderer Grund ist, dass es immer ausschließt, Fremdschlüssel auf mögliche Schlüsselfelder zu setzen (alles, was in der db UNIQUE ist), und das verhindert, dass mehrspaltige Primärschlüssel jemals implementiert werden, was wiederum verhindert, dass Djangos ORM in großen Nicht-Operanden nützlich ist - triviale Schemata. – zxq9