Opened 18 years ago
Closed 17 years ago
#3906 closed (fixed)
Generic Relation query generates incorrect SQL
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Contrib apps | Version: | 0.96 |
Severity: | Keywords: | generic | |
Cc: | mir@… | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Given the following models:
class Entity (models.Model): entity_type = models.CharField(maxlength=30) class PropertyAssertion (models.Model): entity = models.ForeignKey(Entity) assertion = models.GenericForeignKey() content_type = models.ForeignKey(ContentType, core=True) object_id = models.PositiveIntegerField() class Name (models.Model): display_form = models.CharField(maxlength=400, blank=True) assertion = models.GenericRelation(PropertyAssertion)
having a method on the Entity class which performs
Name.objects.filter(assertion__entity=self, assertion__content_type=name_content_type)
(where name_content_type is whatever the content_type of the Name model is in the particular database), the generated SQL (slightly abbreviated in terms of the fields selected) is bogus:
SELECT "eats_core_name".* FROM "eats_core_name" LEFT OUTER JOIN "eats_core_propertyassertion" AS "m2m_eats_core_name__assertion" ON "eats_core_name"."id" = "m2m_eats_core_name__assertion"."object_id" INNER JOIN "eats_core_propertyassertion" AS "eats_core_name__assertion" ON "m2m_eats_core_name__assertion"."object_id" = "eats_core_name__assertion"."id" WHERE ("m2m_eats_core_name__assertion"."entity_id" = 1 AND "m2m_eats_core_name__assertion"."content_type_id" = 31)
This is joining the propertyassertion table to itself, linked by an identity between object_id and id, which have nothing to do with each other. The results of this query are predictably incorrect.
I don't know what the query was which 0.95 generated, but the code seemed to work then and does not with 0.96.
Attachments (1)
Change History (8)
comment:1 by , 17 years ago
Keywords: | generic added |
---|
comment:2 by , 17 years ago
Component: | Uncategorized → Contrib apps |
---|---|
Owner: | changed from | to
comment:3 by , 17 years ago
Has patch: | set |
---|
Ok, I poked around the code, and I think I may have fixed it.
Revision: 5818 django/contrib/contenttypes/generic.py
has the following lines:
def m2m_column_name(self):
return self.object_id_field_name
def m2m_reverse_name(self):
return self.object_id_field_name
Does this seem funny to you?
So I poked around the history, and found that the m2m_reverse_name(self) method use to be:
def m2m_reverse_name(self):
return self.model._meta.pk.attname
When I changed the file to that, querying on the 'backwards' generic relationship now seems to work! Awesome!
Not sure if this fixes your problem, but it fixed my problem!
Added generic.py.patch
comment:4 by , 17 years ago
Cc: | added |
---|
comment:5 by , 17 years ago
Keywords: | qs-rf added |
---|
comment:6 by , 17 years ago
Keywords: | qs-rf removed |
---|
comment:7 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I believe I am having a problem like this as well, any idea if this can be fixed?