tkhyn / django-gm2m

MIT License
35 stars 23 forks source link

wrong related manager for reverse relation #27

Closed tkhyn closed 8 years ago

tkhyn commented 8 years ago

Original report by Han He (Bitbucket: han_he, ).


I encountered an issue that gm2m used the wrong base manager to generate the related manager for reverse query. Below is the sample code.

#!python

class CustomManager(models.Manager):
    def get_queryset(self):
        return super(CustomManager, self).get_queryset().exclude(code='no')

class A(models.Model):
    code = models.CharField(max_length=32)

    objects = CustomManager()

class B(models.Model):
    value = models.CharField(max_length=32)
    items = GM2MField(A)

a = A.objects.create(code='1123')
b = B.objects.create(value='1111')
b.items.add(a)

a.b_set.all()         <-- this would raise an exception "FieldError: Cannot resolve keyword 'code' into field."

It seems the reverse query is using A's default manager, while it should use B's. This should be wrong.

I checked the source code, as I made a change to related_manager_cls in class GM2MUnitRel as below, the exception is gone. But I don't know if this change has any side impact or not. Could you please help take a look? Thanks a lot.

#!python

    @cached_property
    def related_manager_cls(self):
        # the related manager class getter is implemented here rather than in
        # the descriptor as we may need to access it even for hidden relations
        return create_gm2m_related_manager(
            # superclass=self.to._default_manager.__class__,  **change this line to the below one**
            superclass=self.field.model._default_manager.__class__,
            field=self.related.field,
            model=self.field.model,
            through=self.through,
            query_field_name=self.through._meta.model_name,
            field_names=self.through._meta._field_names,
            prefetch_cache_name=self.related.field.related_query_name()
        )
tkhyn commented 8 years ago

Original comment by Thomas Khyn (Bitbucket: tkhyn, GitHub: tkhyn).


Hi there, yes you're right it should be self.field.model instead of self.to as this is a reverse related manager.

Thanks for spotting that / suggesting the fix, I'll include that in the next release.

tkhyn commented 8 years ago

Original comment by Thomas Khyn (Bitbucket: tkhyn, GitHub: tkhyn).


[fix #27] Fixes wrong reverse related manager super class

Thanks @han_he for the fix

tkhyn commented 8 years ago

Original comment by Han He (Bitbucket: han_he, ).


I'm glad my suggestion works. This project is really great, thanks for your work. Hope the next release would come soon. :)