eamigo86 / graphene-django-extras Goto Github PK
View Code? Open in Web Editor NEWExtras functionalities for Graphene-Django
License: MIT License
Extras functionalities for Graphene-Django
License: MIT License
Hi,
Thanks for the lib, i like it very much,
quick question is, seems i can't override the delete method,
I want to check if the products owned by current logged in user before i delete it.
but it seems it's never calling delete and never print product in the console,
create, and update working fine
from rest_framework import serializers
from core.models import Product
class ProductSerializer(serializers.Serializer):
class Meta:
model = Product
def create(self, validated_data):
pass
def update(self, product, validated_data):
pass
def delete(self, product):
if self.logged_in() and product.user.id == self.user().id:
print("product", product)
raise ValidationError(message={"message": "user not logged in"})
In fields.py
in the method list_resolver
(around line 227), I see that filterset_class
is commented out and not used at all.
This prevents one from applying custom filters from django_filter. For instance, I have the following filter:
class ObjectFilter(django_filters.FilterSet):
class Meta:
model = models.Object
fields = ["id"]
# sort is not a field on models.Object, it's just a name I have chosen.
sort = django_filters.OrderingFilter(fields=(
'id', 'created',
))
The problem is that sort
is not a field that exists on the Object
model, but queryset_factory
tries to apply this one in the filter(**kwargs)
method of a model.
This generates errors such as:
graphql.error.located_error.GraphQLLocatedError: Cannot resolve keyword 'sort' into field. Choices are: id, created
So it should apply the filterset class, and ensure that non-model fields are not passed to the filter(**kwargs)
method.
In django-graphene 2.2 iso8601 was removed from requirements
graphql-python/graphene-django@a59f41b
But graphene-django-extras still relies on it, and dont have a requirement for it which will lead into error
Traceback (most recent call last):
File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django_extras/base_types.py", line 13, in
import iso8601
ModuleNotFoundError: No module named 'iso8601'
I installed this great library using pip install and I noticed the tests were installed as well. It should no t be the case.
Hi,
I'm wondering if it's possible to limit the number of subresults as on the example:
https://graphql.org/learn/pagination/
Like
query{
allBrand(brand:"3715ad6b"){
results{
name,
feeds(limit: 2){
media{
image @resize(width:30)
}
}
}
}
or
query{
allBrand(brand:"3715ad6b"){
results{
name,
feeds(first: 2){
media{
image @resize(width:30)
}
}
}
}
Basic example from docs dont work. ( same as with UserType in example)
class PropertyType(DjangoObjectType):
class Meta:
model = models.Property
filter_fields = {
'name': ['icontains']
}
class Query(graphene.ObjectType):
list_properties = DjangoFilterListField(types.PropertyType)
graphene-django-extras 0.3.4a2
graphene-django 2.0.0
Right now i dont see a way to add a custom fields. Like a custom value that is based on other field values.
I am using django-graphql-jwt and it exposes a couple of decorators such as @login_required
that are used to decorate the resolver functions to restrict their access.
How can I use such decorators with DjangoSerializerType
, .ListField()
, RetrieveField()
, etc. I only want to restrict access for certain fields such as:
import graphene
from .types import UserType
class Query(graphene.ObjectType):
users = UserType.ListField()
user = UserType.RetrieveField()
class Mutation(graphene.ObjectType):
update_user = UserType.UpdateField()
Resolvers are not defined in these cases. Any suggestions on how to make it work with django-graphql-jwt
?
Upgrading to the recently released DRF 3.8.x series broke compatibiliy with graphene-django-extras
In DRF 3.8, rest_framework.compat._resolve_model
function has been removed, but it is being imported by utils.py#L15.
I don't feel like opining on the "correct" solution, but since _resolve_model
is only used when Django < 1.9, then making it not only 'conditionally used' but also 'conditionally imported' would make sense to me.
I'm using custom logic for input validation of a model field (like, validate it as a string and then convert it into UUID v.5 before save). So, I have a model and schema defined below:
# models.py
class TestModel(models.Model):
test_field = models.UUIDField()
# schema.py
class TestModelInput(DjangoInputObjectType):
test_field = graphene.String(required=True)
class Meta:
model = TestModel
class CreateTestModel(graphene.Mutation):
class Input:
data = TestModelInput()
@staticmethod
def mutate(root, info, data):
# here I convert and save my model
input TestModelInput {
test_field: String!
...
input TestModelInput {
test_field: UUID!
...
I found out that in the graphene_django_extras/types.py:182
this line
super(InputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
means that the method InputObjectType.__init_subclass_with_meta__
itself is not being called and this class attributes are not being converted into fields. The line should be changed into
super(DjangoInputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
to run correctly.
P.S. Thanks for the great package! It saved me lots of work =)
this commit encode/django-rest-framework@06e2ad0 was recently merged into master in drf breaking ExtraGraphQLView
With the latest 0.13 update, I ran into an issue with the DjangoSerializerMutation update mutation.
I have a model that defines a unique value...e.g.
class User(models.Model):
name = models.CharField(max_length=80, blank=False, null=False, unique=True)
When the call to update is made there is a call to full_clean() on the model with the validated serialized data.
cls._meta.model(**serializer.validated_data).full_clean()
This will fail because it will validate that the name
field is unique for the model.
The quick fix is to change the line to:
cls._meta.model(**serializer.validated_data).full_clean(validate_unique=False)
or to make the call to full_clean optional for the mutation.
It seems that using https://github.com/flavors/django-graphql-geojson raises error here:
Exception: Don't know how to convert the Django field
This is something that can be useful for pagination:
PageGraphqlPagination(max_limit=100)
. This way, someone cannot query all the results.Consider this (dangerous) query:
allUsers() {
results(limit:9999, offset:5) {
...
}
totalCount
limit <-- return the actual limit that is used.
}
}
Without this information, you cannot calculate the right number of pages, because if you assume that you can request 99,999 items, and there are 1,000 items, you would calculate 1 page. But if the server applies a limit (e.g. 100), there is no way that you can determine the number of pages (1,000).
When using the provided get_all_directives
function, the default skip
and include
directives are discarded #50
graphql-python/graphql-core#201
Hi, our team is experiencing issues with graphql-core 2.1 - all queries are erroring if they have a blank value in any enums in the data response. In order to stop this side effect for now, and in accordance with good practice of pinning versions until testing new versions, please pin the packages.
I have a PR with this fix here: #54
Looks like you have another PR with a similar request here: #53
Thanks! The sooner this is fixed the sooner I can help more.
I was happy to learn that graphene added support for turning off camel casing field names.
schema = graphene.Schema(query=Query, auto_camelcase=False)
It all seems to work except for DjangoListObjectType has totalCount. I tried changing it to total_count in the code and was hoping it would get auto-camel cased to totalCount or not depending on the auto_camelcase setting but it didn't.
I don't know the code well enough to provide a PR. Is this something that could be supported?
Is there any good way to start working with django-hvad?
What i found: it create translations_model attribute in _meta of model. So, minimum we must include fields from this model in _meta.fields.
In my opinion, there is no obvious way to add fields from this model. Of course, we can do it manually for all required fields and resolve them from this model, but i think that it is not pretty.
Also, i tried monkeypatch get_model_fields
something like this
old_get_model_fields = converter.get_model_fields
def get_model_fields(model):
fields = old_get_model_fields(model)
if hasattr(model._meta, 'translations_model'):
fields += old_get_model_fields(model._meta.translations_model)
return fields
converter.get_model_fields = get_model_fields
and then i can get fields of translation model and use it in query as normal. But i do not check something like mutations and monkeypatching also is not good way.
So, how make it more clearly?
Hey! Thanks for this amazing utility, definitely it makes using graphene a lot easier with Django.
I'm having this error when trying to implement a filtered query:
Traceback (most recent call last):
File "/home/miltonln/Proyectos/Swapps/accountant-venv/lib/python3.6/site-packages/graphql/execution/executor.py", line 330, in complete_value_catching_error
exe_context, return_type, field_asts, info, result)
File "/home/miltonln/Proyectos/Swapps/accountant-venv/lib/python3.6/site-packages/graphql/execution/executor.py", line 383, in complete_value
raise GraphQLLocatedError(field_asts, original_error=result)
graphql.error.located_error.GraphQLLocatedError: 'NoneType' object has no attribute '_meta'
this is my DjangoObjectType
:
class ProductType(DjangoObjectType):
class Meta:
model = Product
description = "Hey"
filter_fields = {
'name': ['icontains']
}
and this is the query:
class Query(object):
all_product_categories = graphene.List(ProductCategoryType)
all_products = graphene.List(ProductType)
filter_products = DjangoFilterListField(ProductType)
It is correctly connected to the rest of the project schema.
I made some debugging and it seems to be failing in this line, the root
param is None
Am I making some mistake or is this an issue for this library?
Thanks for all the help you can provide to me.
Hi @eamigo86 , thanks for this great library!!!
Can I make a suggestion?
For our mutations, we have some fields that we would like to pass the Foreign Key ID as an update instead of creating a new object, and some fields that we would like to create a new object through a nested structure. In other words, for some fields we want the result of nested_fields
= True (nested object creation), and other fields we want the result of nested_fields
= False (IDs passed in).
Do you think it would be better instead of passing a boolean for the nested_fields, pass a list of fields, to allow only nesting the fields that you specify in DjangoSerializerMutation? Similar to only_fields
?
For example, below for the Foreign Key of Project and the related_name of "products":
class RoomSerializerMutation(DjangoSerializerMutation):
class Meta:
serializer_class = RoomSerializer
nested_fields = ("project", "products", )
All other Foreign Key fields (including Many to Many, One to One, etc.) would take in an ID.
If you agree, I also wanted to get a general understanding of how much time that would take as well. I forked the repo and have been experimented with it to see what I can do to provide this feature myself, but I'm not very confident that I can do it since the codebase is so large and I am just learning it.
Thanks again!
In django-filter you can declare custom FilterSet, and in graphene-django(-extras) you can use it in a custom resolver, but there is not a way to use it in every point the type is referred. I think that it can be resolved by simply adding a filter_set_class
parameter to the DjangoObjectType and using it as default value instead of None
in the call to DjangoFilterListField
in converter.py
.
Hi,
First, thanks for this amazing lib !
I'm wondering if the partial update would be accessible through the class DjangoSerializerMutation ?
At the moment, I use to bypass this issue, the following code:
import functools
def partialclass(cls, *args, **kwds):
class NewCls(cls):
__init__ = functools.partialmethod(cls.__init__, *args, **kwds)
return NewCls
and then
class MediaFeedMutation(DjangoSerializerMutation):
class Meta:
serializer_class = partialclass(MediaFeedSerializer, partial=True)
I'm getting this warning when runing my server
/Users/sgaseretto/.virtualenvs/graphene/lib/python3.6/site-packages/graphene/types/abstracttype.py:9: DeprecationWarning: Abstract type is deprecated, please use normal object inheritance instead.
See more: https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#deprecations
"Abstract type is deprecated, please use normal object inheritance instead.\n"
/Users/sgaseretto/.virtualenvs/graphene/lib/python3.6/site-packages/graphene/types/abstracttype.py:9: DeprecationWarning: Abstract type is deprecated, please use normal object inheritance instead.
See more: https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#deprecations
"Abstract type is deprecated, please use normal object inheritance instead.\n"
[14/Mar/2018 20:02:27] "POST /graphql/ HTTP/1.1" 200 72700
Any idea of how to avoid it?
Hi. Thanks for implementing this stuff. I'm playing around with graphene some time and get piss off on things that were easy in DRF.
I've got problem with implementing DjangoInputObjectType.
This is what i get after just copy-pasting code example:
super(InputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, interfaces=interfaces, **options) TypeError: __init_subclass_with_meta__() got an unexpected keyword argument 'interfaces'
Also, i was trying to implement nested serializer like this:
http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations
but it doesn't seem to do anything. Is it even posible?
First of all: thank you for contributing this! Django is great, GraphQL is great, but Relay was too much for me.
I noticed that queries with fragments are not yet supported. For instance:
query Objects {
object {
results(offset: 0, limit: 20) {
...ObjectFragment
}
totalCount
}
}
fragment ObjectFragment on ObjectType {
id
__typename
}
I have worked around the issue by changing utils.py
on line 105, since it looks like that method only optimizes the query:
...
elif hasattr(field, 'selection_set') and field.selection_set:
...
I found something that might help here. See the get_fields
method.
Here is a traceback:
Traceback (most recent call last):
File "/env/lib/python3.6/site-packages/graphql/execution/executor.py", line 191, in resolve_or_error
return executor.execute(resolve_fn, source, info, **args)
File "/env/lib/python3.6/site-packages/graphql/execution/executors/sync.py", line 7, in execute
return fn(*args, **kwargs)
File "/env/lib/python3.6/site-packages/graphene_django/debug/middleware.py", line 56, in resolve
promise = next(root, info, **args)
File "/env/lib/python3.6/site-packages/graphql/execution/middleware.py", line 57, in make_it_promise
return Promise.resolve(next(*a, **b))
File "/env/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 229, in list_resolver
qs = queryset_factory(manager, info.field_asts, filtering_args, **kwargs)
File "/env/lib/python3.6/site-packages/graphene_django_extras/utils.py", line 131, in queryset_factory
select_related, prefetch_related = recursive_params(fields_asts[0].selection_set, available_related_fields, select_related, prefetch_related)
File "/env/lib/python3.6/site-packages/graphene_django_extras/utils.py", line 106, in recursive_params
a, b = recursive_params(field.selection_set, available_related_fields, select_related, prefetch_related)
File "/env/lib/python3.6/site-packages/graphene_django_extras/utils.py", line 105, in recursive_params
elif field.selection_set:
AttributeError: 'FragmentSpread' object has no attribute 'selection_set'
After last update deps for graphene-django-extras from 0.3.8a9
to 0.3.8a10 via renovate my CI test now throwing a error on launching backend. Work fine with 0.3.8a9.
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 350, in execute
self.check()
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 379, in check
include_deployment_checks=include_deployment_checks,
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 60, in _run_checks
issues.extend(super()._run_checks(**kwargs))
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 366, in _run_checks
return checks.run_checks(**kwargs)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/checks/registry.py", line 71, in run_checks
new_errors = check(app_configs=app_configs)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/checks/urls.py", line 40, in check_url_namespaces_unique
all_namespaces = _load_all_namespaces(resolver)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/checks/urls.py", line 57, in _load_all_namespaces
url_patterns = getattr(resolver, 'url_patterns', [])
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 533, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 526, in urlconf_module
return import_module(self.urlconf_name)
File "/pipeline/source/back/venv/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/pipeline/source/back/hamachi_gql/urls.py", line 22, in <module>
from core.gq.views import HamachiGraphQLView
File "/pipeline/source/back/core/gq/views.py", line 1, in <module>
from graphene_django_extras.views import AuthenticatedGraphQLView
File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django_extras/__init__.py", line 5, in <module>
from .fields import DjangoObjectField, DjangoFilterListField, DjangoFilterPaginateListField, \
File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 7, in <module>
from graphene_django.filter.utils import get_filtering_args_from_filterset
File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django/filter/utils.py", line 3, in <module>
from .filterset import custom_filterset_factory, setup_filterset
File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django/filter/filterset.py", line 5, in <module>
from django_filters import Filter, MultipleChoiceFilter
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django_filters/__init__.py", line 7, in <module>
from .filterset import FilterSet
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django_filters/filterset.py", line 15, in <module>
from .filters import (
File "/pipeline/source/back/venv/lib/python3.6/site-packages/django_filters/filters.py", line 9, in <module>
from django.db.models.sql.constants import QUERY_TERMS
ImportError: cannot import name 'QUERY_TERMS'
My req file
beautifulsoup4==4.6.3
dj-database-url==0.5.0
Django==2.1
django-admin-interface==0.6.3
django-anymail==3.0
django-colorfield==0.1.15
django-cors-headers==2.4.0
django-extensions==2.1.0
django-fsm==2.6.0
django-graphiql-debug-toolbar==0.1.1
django-graphql-extensions==0.0.4
django-graphql-jwt==0.1.10
django-mail-templated-simple==3.2
graphene==2.1.3
graphene-django==2.1.0
graphene-django-extras==0.3.8a10
Jinja2==2.10
pinax-stripe==4.4.0
psycopg2==2.7.5
pyjade==4.0.0
python-dateutil==2.7.3
python-decouple==3.1
PyYAML==3.13
requests==2.19.1
six==1.11.0
stringcase==1.2.0
matplotlib==2.2.3
zappa==0.46.2
zappa-django-utils==0.4.0
django-storages==1.6.6
boto3==1.7.75
faker==0.9.0
raven==6.9.0
django-constance==2.2.0
django-picklefield==1.0.0
attrs==18.1.0
simplejson==3.16.0
phonenumbers==8.9.10
Hello, is there a direct (clear) way for accessing amount of objects returned by DjangoFilterPaginateListField?
I need amount of filtered objects before they are split to pages.
Example: if I have 10 objects in db, I filter them by some key and I get 7 objects. I will be paginating this result but I still need the number (7) of objects returned by filter.
Thank you!
Hey,
I'm setting up a basic sample project for testing purposes in a fork of your repository, and I stumbled upon this issue when using LimitOffsetGraphqlPagination here: https://github.com/dperetti/graphene-django-extras/blob/7c9e38b9136681cd6522744eb151fbefe0d483aa/sampleproject/sampleproject/schema.py#L69
Looks very much like a circular import issue.
Can you have a look ?
Hey! Thanks for this package ๐
I got exception on using DEFAULT_PAGINATION_CLASS
.
settings.py
GRAPHENE_DJANGO_EXTRAS = {
'DEFAULT_PAGINATION_CLASS': 'graphene_django_extras.paginations.LimitOffsetGraphqlPagination',
'DEFAULT_PAGE_SIZE': 50,
'MAX_PAGE_SIZE': 100
}
I'm using DjangoFilterPaginateListField
without pagination parameter:
# types.py
class PositionType(DjangoObjectType):
class Meta:
model = models.Position
filter_fields = {
'name': ['exact', 'icontains', 'istartswith'],
'id': ['exact']
}
# schema.py
class Query(ObjectType):
positions = DjangoFilterPaginateListField(types.PositionType)
Traceback:
File "/usr/local/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 132, in __init__
).format(pagination)
AssertionError: You need to pass a valid DjangoGraphqlPagination in DjangoFilterPaginateListField, received "<class 'graphene_django_extras.paginations.pagination.LimitOffsetGraphqlPagination'>".
graphene_django_extras/fields.py
isinstance(pagination, BaseDjangoGraphqlPagination)
on 142 line.
Code from sources:
pagination = pagination or graphql_api_settings.DEFAULT_PAGINATION_CLASS
if pagination is not None:
assert isinstance(pagination, BaseDjangoGraphqlPagination), (
'You need to pass a valid DjangoGraphqlPagination in DjangoFilterPaginateListField, received "{}".'
).format(pagination)
I have a type with a calculated field who depends on a model related field, can you add a way to tag it for prefetch?
My idea:
class PersonType(DjangoObjectType):
class Meta:
model = Person
display = graphene.String()
@dependes_on('user')
def resolve_display(self, info):
return str(self.user)
This way every access to display will implay a fetch of user.
For example i want to filter articles by current user using DjangoListObjectField or DjangoFilterPaginateListField
I dont see a clean way to do so right now. In django-graphene for DjangoConnectionField i could define resolve_articles field. It doesnt work here.
Other options would be to use django-filter request filtering by defining a custom filterset_class. https://django-filter.readthedocs.io/en/latest/guide/usage.html#filtering-the-primary-qs
But request not passed to filterset at all
https://github.com/eamigo86/graphene-django-extras/blob/master/graphene_django_extras/fields.py#L188 only qs and data passed. Something like request=info.context is missed.
Am i missing something?
Just wondering if it is possible to define custom resolver for the fields exposed by graphene-django-extras.
My project has two Apps (with separate databases) but with relationships across apps.
I would like to use a custom resolver to select related objects where the connection is not defined in the ORM but still have access to pagination and filtering.
I tried to do this as I would in Graphene-Django but the resolver function isn't called when used with any of the fields provided by this library. I tried it with graphene.field and the resolver function is run.
class SiteObjectType(DjangoObjectType):
class Meta:
description = "Site model type definition "
model = models.Site
vehicles = DjangoListObjectField(types.Vehicle)
def resolve_vehicles(self, info, **kwargs):
# something like this to select the relevant vehicle objects
related_vehicles = Vehicles.object.filter(id__in="self.id")
return related_vehicles
Is this expected behaviour and is there any way around it?
Thanks for the great work on this extension!
'<' not supported between instances of 'GenericForeignKey' and 'DateTimeField'
.
The exception is triggered here : https://github.com/eamigo86/graphene-django-extras/blob/master/graphene_django_extras/utils.py#L22 when using a type like this :
class CommentType(DjangoObjectType):
class Meta:
model = Comment
For a model like this:
class Comment(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
Hi,
first of all: awesome package!
I don't really have an issue to report, but a feature that should be documented and was hard for me to find.
My problem was that I intended to use DjangoSerializerType for common queries and mutations. Everything worked fine, apart from including property functions from the django model. I had to define a baseType like this, which worked fine:
class InstrumentType(DjangoObjectType):
is_at = graphene.Field(LocationType.object_type(), source='is_at')
class Meta:
model = Instrument
But then I couldn't use the nice features of DjangoSerializerType or DjangoListObjectType. Then I searched for a long time how to pass that InstrumentType to e.g. a DjangoSerializerType. Finally I found out that you use this line in the types.py to get an already defined baseType from the registry:
output_type = registry.get_type_for_model(model)
if not output_type:
output_type = factory_type('output', DjangoObjectType, **factory_kwargs)
But this depends on the order of the type definitions in the source code and is real implicit behaviour.
After I found that out, I could use my InstrumentSerializerType with correct custom baseType just like this:
class InstrumentSerializerType(DjangoSerializerType):
class Meta:
serializer_class = InstrumentSerializer
I really suggest you document that behaviour, since it's a powerful feature and can also have unexpected negative effects if you don't know about.
Thanks for the nice work,
Greets,
Bene
I've defined a simple DjangoListObjectType with just a model and pagination attributes in the Meta and when added to Query with DjangoListObjectField I can't get the resolve_[field_name] method called.
Is this an intended behavior? How can I intervene the list/queryset? I wanted to filter out some elements.
Just as a reference of my intention:
class Product(models.Model):
name = models.CharField(max_length=255)
discontinued = models.BooleanField(default=False)
class ProductListType(DjangoListObjectType):
class Meta:
model = Product
pagination = LimitOffsetGraphqlPagination()
class Query(graphene.ObjectType):
all_products = DjangoListObjectField(ProductListType)
def resolve_all_products(self, info, **kwargs):
qs = Product.objects.all()
some_parameter = kwargs.get('some_parameter')
if some_parameter is not None:
qs.exclude(discontinued=True)
return qs
Thanks a lot!
Hi Sir,
Much appreciate for the lib you are working on! i like it very much.
I wonder if you can give me some guidance on how init_subclass_with_meta works,
i keep investigating in the source code and other examples but still can't figure it out.
in this method:
def __init_subclass_with_meta__(cls, serializer_class=None, only_fields=(), exclude_fields=(),
save_resolver=None, delete_resolver=None,
input_field_name=None, output_field_name=None, description='',
nested_fields=False, **options):
if not serializer_class:
raise Exception('serializer_class is required on all DjangoSerializerMutation')
the point confused me is I didn't find anywhere that init_subclass_with_meta get called as a classmethod in my code,
and never manually pass serializer_class into this function, wonder how does line if not serializer_class:
working properly? why it can automatically detect i assigned serializer_class in my Meta subclass in which inherited from DjangoSerializerMutation class?
much appreciated!
This a minor but annoying issue when you use a front end tool like Apollo because it results in weaker typing.
It affects graphene-django as well, but I have more confidence in graphene-django-extras to fix it ! :-)
Here it is: results should not be of the form results: [UserType]
but results: [UserType!]
since returned objects in the array can't be null.
I don't know if it's somehow related, but the same issues applies to related objects resulting from foreign keys or M2M.
I'm using django-unixtimestampfield, and some error is raised.
File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 226, in __init__ self.filterset_class = get_filterset_class(filterset_class, **meta) File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/graphene_django_extras/filters/filter.py", line 12, in get_filterset_class return custom_filterset_factory(**meta) File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/graphene_django_extras/filters/filter.py", line 42, in custom_filterset_factory 'Meta': meta_class File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/django_filters/filterset.py", line 71, in __new__ new_class.base_filters = new_class.get_filters() File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/django_filters/filterset.py", line 345, in get_filters filters[filter_name] = cls.filter_for_field(field, field_name, lookup_expr) File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/django_filters/filterset.py", line 377, in filter_for_field ) % (cls.__name__, field_name, lookup_expr, field.__class__.__name__) AssertionError: UserFilterSet resolved field 'created_at' with 'exact' lookup to an unrecognized field type UnixTimeStampField. Try adding an override to 'Meta.filter_overrides'. See: https://django-filter.readthedocs.io/en/master/ref/filterset.html#customise-filter-generation-with-filter-overrides
`
from unixtimestampfield.fields import UnixTimeStampField
class TimestampMixin(models.Model):
created_at = UnixTimeStampField(db_column="crt_at", use_numeric=True, auto_now_add=True, editable=False)
updated_at = UnixTimeStampField(db_column="udt_at", use_numeric=True, auto_now=True)
class Meta:
abstract = True
`
The codes seems not passing context to serializer when it's called.
serializer = cls._meta.serializer_class(data=new_obj)
I would like to add request.user
when it tries to save, I couldn't find a way to do it.
Anyone has done this before?
Hi @eamigo86, thanks for sharing this!
I was struggling with Django ORM errors like:
Invalid field name(s) given in select_related: 'my_field'. Choices are: my_other_field, another_one, ...
In particular, this happens when both querying AND filtering by a many-to-many or one-to-many relation field.
If i'm not missing something, there seems to be a subtle bug over utils.recursive_params()
that leads to such fields being used as arguments for prefetch_related
(expected) and simultaneously for select_related
(unexpected) if they're "visited" more than once within the recursion.
I made a pull request #42 which fixes this issue for me, by adjusting this duplicate-preventing conditional that misidentifies already-added fields meant for prefetch_related
as fields meant for select_related
.
Hello @eamigo86,
I'm having some trouble with creating nested objects like in DRF as explain in your post https://github.com/graphql-python/graphene-django/issues/274#issuecomment-335191042
Here's what I got in serializers.py:
class BookingSerializer(serializers.ModelSerializer):
class Meta:
model = Booking
fields = (
'status'
)
class OtherBookingSerializer(serializers.ModelSerializer):
booking = BookingSerializer()
class Meta:
model = OtherBooking
fields = (
'id',
'first_name',
'last_name',
'sex',
'birthday',
'language',
'emergency',
'booking'
)
def create(self, validated_data):
booking_data = validated_data.pop('booking')
other_booking = OtherBooking.objects.create(**validated_data)
Booking.objects.create(otherbooking=other_booking, **booking_data)
return other_booking`
then in GraphQL, following this example : https://user-images.githubusercontent.com/11740026/31345324-090bfc78-acdb-11e7-9194-ad2bb4f8fdaa.png, it says that field 'booking' is required; but when I put it in my query, it says "unknown field"...
for info, here is what I got on schema.py:
class BookingParticipantStatusSerializerMutation(DjangoSerializerMutation):
"""
DjangoSerializerMutation auto implement Create, Delete and Update functions
"""
class Meta:
description = " DRF serializer based Mutation for Users "
serializer_class = OtherBookingSerializer
nested_fields = True
class Mutations(graphene.ObjectType):
create_booking_participant_status = BookingParticipantStatusSerializerMutation.CreateField()
update_booking_participant_status = BookingParticipantStatusSerializerMutation.UpdateField()`
I'm struggling to find where the problem comes from.
Any help would be much appreciated!
Thanks in advance!
Using DjangoListObjectType to make a filterable list doesn't make any related field available on the graphql endpoint.
I have a related field called created_by (ForeignKey to User model) but I can't query it on DjangoListObjectField, only on DjangoObjectField. Is there any way I can do that?
In converter.py
on line 4, fields from PostgreSQL are imported.
These fields are only available when you have the psycopg2
module installed. This module is not listed in setup.py
, but I think it is better to not depend on this if the user does not use PostgresQL.
Hi,
Hope this issue helps others out. I was trying to import all_directives like in the README and getting an error since it hasn't been updated on PyPi.
I can resolve this by installing directly from GitHub/installing 0.3.8a8, but it'd probably make sense to update the PyPi package/make a note on the README.
I'm trying to create some update mutations, where I don't want to pass some fields, because I don't want to update them.
For example I have this model:
class Pet(models.Model):
name = models.CharField(max_length=60)
description = models.TextField(blank=True, null=True)
owner = models.ForeignKey(settings.AUTH_USER_MODEL)
And the following InputType:
class PetInput(DjangoInputObjectType):
class Meta:
model = Pet
description = 'Pet InputType'
How can I change, for example, the name and owner fields from my InputType in order to make them required=False. As a suggestion, it will be nice adding something like the exclude_fields = ('name', 'owner')
that makes them required=False, for example a require_false_fields = ('name', 'owner')
I just don't know how something like this could be implemented
Hello,
Django-filters version has been pinned to 1.1 due to its incompatibility with django 2 (I assume). As the version 2 has been released, do you know what would be needed to have it updated such that we could use graphene-django-extras with django 2 or is it compatible out of the box ?
Thanks
Very possible that I'm missing something, but my model contains this property:
@property
def name_string(self):
return '%s %s %s' % (
self.model_year,
self.model_name,
self.trim
)
Serializer:
class VehicleSerializer(serializers.ModelSerializer):
name_string = serializers.ReadOnlyField()
class Meta:
model = Vehicle
fields = '__all__'
read_only_fields = ('name_string')
SerializerType:
class VehicleModelType(DjangoSerializerType):
class Meta:
description = "Vehicle Model Type Definition"
serializer_class = VehicleSerializer
pagination = LimitOffsetGraphqlPagination(default_limit=25)
filter_fields = {
'stock': ['exact', ],
'active': ['exact', ],
}
However, name_string or nameString isn't an option when querying. Not sure if GDE looks for them, or what I need to do?
In Django Rest Framework 3.7.0 (released a few days ago), the above method is removed (see here).
Reverting back to 3.6.0 fixes it, for now.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.