Repository: graphql-python/graphene-django

Issue:
M2M connection is broken
Hi,

I have following models:

```
class Place(models.Model):
    categories = models.ManyToManyField(PlaceCategory, related_name='places')
```
```
class PlaceCategory(models.Model):
    name = models.CharField(max_length=255, unique=True)
```
Furthermore, I have following DjangoObjectType models:

```
class PlaceNode(DjangoObjectType):
    class Meta:
        model = Place
        interfaces = (graphene.relay.Node, )
```
```
class PlaceCategoryNode(DjangoObjectType):
    class Meta:
        model = PlaceCategory
        interfaces = (graphene.relay.Node, )
```

Then when I execute this query:
```
{
  placeCategories {
    edges {
      node {
        id
        places {
          edges {
            node {
              id
            }
          }
        }
      }
    }
  }
}
```

everything works great but when I try to execute this one:
```
{
  places {
    edges {
      node {
        id
        categories {
          edges {
            node {
              id
            }
          }
        }
      }
    }
  }
}
```
I get errors: 
> Cannot combine queries on two different base models.

It seems that M2M connection is working improperly and it is unable to fetch related objects from instance where M2M is defined.

Has anyone run into the same problem ?


Discussion:
Issue seems to be related to: https://github.com/graphql-python/graphene/issues/466
Do you have any ideas for a work around? I have just run into this issue.
You can just define custom resolver and return queryset. It should work.

In my case it would be:
```
class PlaceNode(DjangoObjectType):
    class Meta:
        model = Place
        interfaces = (graphene.relay.Node, )

    categories = DjangoFilterConnectionField(PlaceCategoryNode)

    def resolve_categories(self, *args):
        return self.categories.all()
```

But this is only a workaround. In my case when I have lots of M2M it is annoying that I have to define custom resolvers for all of them.
It looks that exception is raised by:
```
DjangoConnectionField.merge_querysets
```

Method gets two queryset, `default_queryset` and `queryset`. Although `queryset` contains proper instances from m2m connection,  `default_queryset` contains all objects from base model. In my case `queryset` has PlaceCategory instances while `default_queryset` has Place instances. That's why it raises error.

 Looks to me that `DjangoFilterConnectionField.connection_resolver` receives wrong `default_manager` parameter.

Can anyone confirm this ?

Resolving patch:
diff --git a/graphene_django/utils.py b/graphene_django/utils.py
--- a/graphene_django/utils.py
+++ b/graphene_django/utils.py
@@ -21,8 +21,12 @@ class LazyList(object):
     DJANGO_FILTER_INSTALLED = False
 
 
-def get_reverse_fields(model):
+def get_reverse_fields(model, local_field_names):
     for name, attr in model.__dict__.items():
+        # Don't duplicate any local fields
+        if name in local_field_names:
+            continue
+
         # Django =>1.9 uses 'rel', django <1.9 uses 'related'
         related = getattr(attr, 'rel', None) or \
             getattr(attr, 'related', None)
@@ -44,15 +48,18 @@ def maybe_queryset(value):
 
 
 def get_model_fields(model):
-    reverse_fields = get_reverse_fields(model)
-    all_fields = [
+    local_fields = [
         (field.name, field)
         for field
         in sorted(list(model._meta.fields) +
                   list(model._meta.local_many_to_many))
     ]
 
-    all_fields += list(reverse_fields)
+    # Make sure we don't duplicate local fields with "reverse" version
+    local_field_names = [field[0] for field in local_fields]
+    reverse_fields = get_reverse_fields(model, local_field_names)
+
+    all_fields = local_fields + list(reverse_fields)
 
     return all_fields
 


Test patch:
diff --git a/graphene_django/tests/test_utils.py b/graphene_django/tests/test_utils.py
new file mode 100644
--- /dev/null
+++ b/graphene_django/tests/test_utils.py
@@ -0,0 +1,12 @@
+from ..utils import get_model_fields
+from .models import Film, Reporter
+
+
+def test_get_model_fields_no_duplication():
+    reporter_fields = get_model_fields(Reporter)
+    reporter_name_set = set([field[0] for field in reporter_fields])
+    assert len(reporter_fields) == len(reporter_name_set)
+
+    film_fields = get_model_fields(Film)
+    film_name_set = set([field[0] for field in film_fields])
+    assert len(film_fields) == len(film_name_set)