New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is totalCount not implemented on Relay? #162
Comments
class Product(graphene_django.DjangoObjectType):
...
@classmethod
def get_connection(cls):
class CountableConnection(graphene.relay.Connection):
total_count = graphene.Int()
class Meta:
name = '{}Connection'.format(cls._meta.name)
node = cls
@staticmethod
def resolve_total_count(root, args, context, info):
return root.length
return CountableConnection |
Not sure what you did there. If you could put it in the context of my code it would be more understandable, and if you provide some explanations, we could upgrade this question to the doc status :) Since Relay has the concept of totalCount, developers would expect it available in the query.
|
Ok so here's what happens: when you implement the Look at the method def implements(cls, objecttype):
get_connection = getattr(objecttype, 'get_connection', None)
if not get_connection:
get_connection = partial(get_default_connection, objecttype)
objecttype.Connection = get_connection() you'll notice it attemps to find a ...
from graphene import Int
class ProductNode(DjangoObjectType):
class Meta:
model = Product
filter_fields = {
'name': ['exact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, )
@classmethod
def get_connection(cls):
class CountableConnection(relay.Connection):
total_count = Int()
class Meta:
name = '{}Connection'.format(cls._meta.name)
node = cls
@staticmethod # Redundant since Graphene kinda does this automatically for all resolve_ methods.
def resolve_total_count(root, args, context, info):
return root.length
return CountableConnection That's it... I hope. Also, thanks to how Python's scoping works, the outer Also, the Hope I cleared any doubts |
Will try, but wouldn't it be easier to just stick is somewhere here in the Connection? |
Yes, it definitely would. But I am merely proposing a solution that works with the current version of Graphene, though :) |
I can wait for few days no worries :) |
The solution worked for me. Because this is scensial to paginate, I've done it as a Mixin to add it to multiple class TotalCountMixin(ObjectType):
@classmethod
def get_connection(cls):
class CountableConnection(relay.Connection):
total_count = Int()
class Meta:
name = '{}Connection'.format(cls._meta.name)
node = cls
@staticmethod
def resolve_total_count(root, args, context, info):
return root.length
return CountableConnection Then I added it to the DjangoObjectType, in your case it would be: class ProductNode(DjangoObjectType, TotalCountMixin):
class Meta:
model = Product
filter_fields = {
'name': ['exact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, ) Test it! |
@Fercho191 Thank you for sharing your Mixin! :D |
The |
This is how to do it in version 2 (graphene is woefully undocumented) :(
|
Thanks @aminland. Unfortunately when I try make it using abstract class I get class EventType(DjangoObjectType):
class Meta:
model = Event
interfaces = (graphene.relay.Node, )
class CountableConnection(graphene.relay.Connection):
total_count = graphene.Int()
class Meta:
node = EventType
def resolve_total_count(self, info):
return self.iterable.count()
class UserProfilType(DjangoObjectType):
events = graphene.relay.ConnectionField(CountableConnection)
class Meta:
model = UserProfil
interfaces = (graphene.relay.Node, ) |
@igo |
Are you using v2.0?
…On Dec 2, 2017 4:23 AM, "Igor Urminček" ***@***.***> wrote:
Thanks @aminland <https://github.com/aminland>. Unfortunately when I try
make it using abstract class I get TypeError: Error when calling the
metaclass bases __init_subclass_with_meta__() got an unexpected keyword
argument 'connection_class' Any ideas?
Meanwhile I was able to make it work with
class EventType(DjangoObjectType):
pass
class CountableConnection(graphene.relay.Connection):
total_count = graphene.Int()
class Meta:
node = EventType
def resolve_total_count(self, info):
return self.iterable.count()
class UserProfilType(DjangoObjectType):
events = graphene.relay.ConnectionField(CountableConnection)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#162 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAOFkIcoh9gLMhX4VDHgyr5JZh8eICweks5s8RccgaJpZM4NLXoS>
.
|
@aminland |
@igo where does the Event model come from? |
@igo This worked fine, for relay.ConnectionField, but didn't for DjangoConnectionField, because it fails an assert in class CustomDjangoConnectionField(DjangoConnectionField):
@property
def type(self):
from .types import DjangoObjectType
_type = super(ConnectionField, self).type
# assert issubclass(_type, DjangoObjectType), "DjangoConnectionField only accepts DjangoObjectType types"
assert _type._meta.connection, "The type {} doesn't have a connection".format(_type.__name__)
return _type._meta.connection Note the wonky call to super() to skip the baseclass. I ended up implementing the connection type directly in type(), see my comment in #320 , as this is a common case in our code base. |
@aminland I think the version on pypi (https://pypi.python.org/pypi/graphene-django/2.0.0) does not expose |
Yep that’s what we did but would be nice to have it in a stable release as this is necessary for pagination. |
referred to as connection_class, it will instantiate the connection from the provided class or default to graphene.Connection if not supplied
Any reason why this hasn't been released on PyPI yet? 2a39f5d#diff-6926ea790e42fa924302b75462dfef72 It's been over 8 months, would be great to be able to use this sort of functionality. |
This should have been released now so closing. |
IMHO |
@zbyte64 +1. Maybe we should reopen this issue? |
Why is this issue closed? As far as I'm concerned, the issue is still there in v2.15.0 because |
This gives me an error in /graphql. Rest works like a charm though.
The text was updated successfully, but these errors were encountered: