question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use DjangoObjectType (or something like it) as an Input class?

See original GitHub issue

We’re using Graphene with Relay for some boring CRUD style mutations. Now, since we have some rather large (i.e., many fields) models, it’s a bit tedious and also error-prone, to repeat typing in the model’s fields again for each mutation. Is it possible to use DjangoObjectType for this (from my 1st try it seems that, no)?

I’m mainly interested in the Meta class’ model and only_fields options.

And guys, thanks for the hard work on such a cool tool.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:24
  • Comments:13

github_iconTop GitHub Comments

7reactions
charlesverdadcommented, Sep 18, 2018

I was able to dynamically generate an Input class from Model using a Django Rest Framework serializer and the convert_serializer_to_input_type tool in graphene_django.rest_framework.serializer_converter.

Sample Code:

from rest_framework import serializers
from graphene_django.rest_framework.serializer_converter import convert_serializer_to_input_type

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        exclude = ('profile',)

class PersonArgsInput(convert_serializer_to_input_type(PersonSerializer)):
    create = graphene.Boolean(required=True)

In the above code I [optionally] created a PersonArgsInput, which inherits from the generated Input class, so I can add additional fields. I can then use the the new class in my mutations however I want. like so:

class PersonsMutation(graphene.Mutation):
    person_set = graphene.List(PersonType)
    class Arguments:
        person_set = graphene.List(PersonArgsInput)
    def mutate():
    ...
3reactions
nuschkcommented, Feb 27, 2017

Here’s something I put together, which seem to work, but is certainly work in progress:

import collections
from graphene_django import converter, utils

from graphene.types.utils import merge
from graphene.utils.is_base_type import is_base_type


def convert_fields(model, only_fields):
    model_fields = utils.get_model_fields(model=model)
    fields = collections.OrderedDict()

    for field in model_fields:
        name = field.name

        # Must be in only_fields
        if name not in only_fields:
            continue

        converted = converter.convert_django_field(field, None)
        if not converted:
            continue

        fields[name] = converted

    return fields


class DjangoModelInputMeta(type):

    @staticmethod
    def __new__(cls, name, bases, attrs):
        # We'll get called also for non-user classes like DjangoModelInput. Only
        # kick in when called for a sub-class.
        if not is_base_type(bases, DjangoModelInputMeta):
            return type.__new__(cls, name, bases, attrs)

        # Pop Meta info. Must be removed from class, otherwise graphene will
        # complain.
        meta = attrs.pop('Meta')
        fields = convert_fields(model=meta.model, only_fields=meta.only_fields)
        attrs = merge(attrs, fields)

        return type.__new__(cls, name, bases, attrs)


class DjangoModelInput(metaclass=DjangoModelInputMeta):
    """
    Derive a mutation's Input class from this and define a meta class with 
    `model` and `only_fields` members. This will populate the input class
    with the converted django members.
    """
    pass

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a way to elegantly use a django model as an input ...
It would be nice if you could subclass something like "DjangoInputObjectType" and specify the model and fields you want in a Meta attribute....
Read more >
Queries & ObjectTypes - Graphene-Python
A Resolver that maps to a defined DjangoObjectType should only use methods that return a queryset. Queryset methods like values will return dictionaries,...
Read more >
Django + Graphene: From REST to GraphQL - FullStack Labs
Now, just like that, our app is available to respond to graphQL queries. Here we are using the logic directly, but you can...
Read more >
graphene-django-extras - PyPI
This library add some extra funcionalities to graphene-django to facilitate ... definition to use as input on an Arguments class on traditional Mutations ......
Read more >
How to add GraphQL to DjangoCMS | Articles | Bravelab.io
Create a file schema.py and import DjangoObjectType. Create a class Query that will hold all of ... Inside Meta class configure what django...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found