graphene-django icon indicating copy to clipboard operation
graphene-django copied to clipboard

DjangoFormMutation should allow filtering of input and output separately

Open jtratner opened this issue 5 years ago • 3 comments

DjangoFormMutation by default filters both input and output fields based on only_fields and exclude_fields. Ideally it'd allow you to filter input and output separately. (I'm going to put up a PR alongside this, but figured it was best form to have an issue too).

Desired Behavior vs. Actual Behavior

Desired Behavior: Mutation that has a payload with only clientMutationId + my custom output field, while still having all input fields Actual Behavior: either have to filter out all input fields (making form unusable) or end up pushing out all of the input fields into the outputted payload (which doesn't quite make sense to me)

Background and Example

Imports + model definition + form definition

from graphene_django import DjangoObjectType
from graphene import relay, ObjectType, Int
from graphene_django.forms.types import ErrorType
from graphene_django.forms.mutation import DjangoFormMutation
from spar_web.core.models import Report
from django import forms
from django.db import models
import graphene

class Report(models.Model): display_name = models.CharField(max_length=255) config = models.CharField(max_length=255) directory = models.CharField(max_length=255)

class CreateReportForm(forms.Form): display_name = forms.CharField() report_type = forms.CharField() directory = forms.CharField() config = forms.CharField(required=False)

def clean(self):
    if self.errors:
        return
    cleaned_data = super().clean()
    if not cleaned_data.get('config'):
        # dummy example
        cleaned_data['config'] = cleaned_data['report_type'] + 'config'
    return cleaned_data

class ReportNode(DjangoObjectType):
    class Meta:
        model = Report
        interfaces = (relay.Node,)


class CreateReportMutation(DjangoFormMutation):
    report = graphene.Field(ReportNode)

    class Meta:
        form_class = Create
        only_fields = ['report']

    @classmethod
    def perform_mutate(cls, form, info):
        data = form.cleaned_data
        obj = Report.objects.create(
            display_name=data['display_name'],
            directory=data['directory'],
            config=data['config']
        )
        kwargs = {'report': obj}
        return cls(errors=[], **kwargs)


class Query(graphene.ObjectType):
    report = relay.Node.Field(ReportNode)


class Mutation(graphene.ObjectType):
    create_report = CreateReportMutation.Field()

schema = graphene.Schema(
    query=Query,
    mutation=Mutation
)

jtratner avatar Apr 15 '20 22:04 jtratner

(pushed PR with example in #934 :) )

jtratner avatar Apr 15 '20 22:04 jtratner

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Aug 14 '20 09:08 stale[bot]

Any update on this?

ruohola avatar Apr 05 '21 12:04 ruohola