Currently, only built in model field types are supported.
If you try to use alternative field types (such as currency fields provided by https://github.com/django-money/django-money), they cause this error:
web_1 | File "/usr/local/lib/python3.5/site-packages/graphene_django/converter.py", line 58, in convert_django_field
web_1 | (field, field.__class__))
web_1 | Exception: Don't know how to convert the Django field renting.RenterProfile.phone_number (<class 'phonenumber_field.modelfields.PhoneNumberField'>)
There should probably be some API exposed to register conversions for additional field types. (Or if this is already possible, explain it in the docs.)
I think I found a solution registering the custom field in schema.py immediately below the last import. F.i. if you need to register CustomField in the cookbook example you should have something like this:
import cookbook.ingredients.schema
import graphene
from graphene_django.converter import convert_django_field
from graphene_django.debug import DjangoDebug
@convert_django_field.register(CustomField)
def my_convert_function(field, registry=None):
# Customization here
return something
class Query(cookbook.ingredients.schema.Query, graphene.ObjectType):
debug = graphene.Field(DjangoDebug, name='__debug')
schema = graphene.Schema(query=Query)
It seems working, but since there's no documentation about this it could be terribly wrong.
The solution proposed by @marbont would definitely work.
However I think we should choose an approach similar to Django Admin formfield_overrides.
Probably having something like:
def convert_phonenumberfield(field, registry=None):
return graphene.String()
class Transaction(DjangoObjectType):
class Meta:
model = TransactionModel
field_overrides = {
MoneyField: graphene.String,
# Also accepts a function for conversion
PhoneNumberField: convert_phonenumberfield
}
Thoughs?
@syrusakbary I don't really like that approach, namely because it would mean I need to set field_overrides for every model in my schema where I use a non-standard field: very un-DRY. Ideally, other libraries (which furnish custom fields) should be able to automatically handle registration. It seems like I should only have to say how to convert a certain field type once.
Sounds reasonable.
I would go with the solution provided by @marbont then:
import graphene
from graphene_django.converter import convert_django_field
@convert_django_field.register(CustomField)
def my_convert_function(field, registry=None):
return graphene.String()
If you think we should provide a cleaner API for registering field conversion, any ideas will be welcome!
Once we agree on a way for registering, we can make it official by having a page on the docs with the recommended way to add additional types.
@syrusakbary Should that be working as is? Somehow I had problems with it, but I can take a look again.
As long as is the "register" happens before the creation of a DjangoObjectType we should be covered.
However if you see any issue with that just ping here and we can work on it! :)
Hi i have the same issue and i added this to the schema.py :
from graphene_django.converter import convert_django_field
from phonenumber_field.modelfields import PhoneNumberField
@convert_django_field.register(PhoneNumberField)
def convert_phone_number_to_string(field, registry=None):
return graphene.String( description=field.help_text, required=not field.null)
but i got the same :
"Don't know how to convert the Django field paid_ads.Client.phone (
I did'nt found any doc for this. Can anyone explain how to register a new type? Thanx
@reinierpd
I was getting this error and as a workaround I had to import my schema only after registering my CustomField converter.
If I put this line import cookbook.schema in the imports section the will raise the error again.
import graphene
from graphene_django.converter import convert_django_field, convert_field_to_string
from geoposition.fields import GeopositionField
@convert_django_field.register(GeopositionField)
def convert_geofield_to_string(field, registry=None):
return graphene.String(description=field.help_text, required=not field.null)
import cookbook.schema
class Query(cookbook.schema.Query, graphene.ObjectType):
# This class extends all abstract apps level Queries and graphene.ObjectType
pass
schema = graphene.Schema(query=Query)
Hello! I'm building a photo library site and use django-imagekit package, which has imagekit.models.ImageSpecField to represent processed-on-demand version of django.db.models.ImageField.
In models.py I have:
class Photo(models.Model):
img = models.ImageField(upload_to='images')
thumb = ImageSpecField(source='img', processors=[ResizeToFit(100,100)])
In schema.py:
```
@converter_django_field.register(ImageSpecField)
def convert_ImageSpecField(field, registry=None):
return graphene.String()
class PhotoType(DjangoObjectType):
class Meta:
model = Photo
def resolve_img(self, *_):
return '{}{}'.format(MEDIA_URL, self.img)
class Query(graphene.AbstractType):
photos = graphene.List(PhotoType)
def resolve_photos(self, *_):
return Photo.objects.all()
````
When I query for {photos{img}}, I get what I expect: relative urls of img fields.
But when I ask for {photos{thumb}}, I get error message: "Cannot query field \"thumb\" on type \"PhotoType\".". And thumb field is not present when I browse API in GraphiQL.
Did I do it wrong? Is it possible to do?
from phonenumber_field.modelfields import PhoneNumberField
@convert_django_field.register(PhoneNumberField)
def convert_phonenumberfield(field, registry=None):
return graphene.String()
Most helpful comment
@reinierpd
I was getting this error and as a workaround I had to import my schema only after registering my CustomField converter.
If I put this line
import cookbook.schemain the imports section the will raise the error again.