Using Django and GraphQL to manage money and finances? Check out graphene-djmoney

Using Django and GraphQL to manage money and finances? Check out graphene-djmoney

At Uplift, we work a lot with Django and GraphQL, and rely heavily on graphene. Sometimes you need to work with money and currencies, and for this, it's hard to beat the Django integration offered by django-money.

We wanted a nice way to handle GraphQL APIs for these Money types too, and wrote an open source library for it.

Introducing graphene-djmoney

GraphQL Money types for Django using graphene and django-money (djmoney). If you use django, graphene_django, and django-money, this library is for you.

You get automatic resolvers for MoneyField model fields:

from django.conf import settings
from django.db import models
from djmoney.models.fields import MoneyField

class Product(models.Model):
    # ... other fields ...
	cost = MoneyField(
        max_digits=settings.CURRENCY_MAX_DIGITS,
        decimal_places=settings.CURRENCY_DECIMAL_PLACES,
        default_currency=settings.BASE_CURRENCY,
        null=True,
        blank=True,
    )

Then your graphene GraphQL product type:

import graphene
from graphene_django import DjangoObjectType

from yourapp import models


class Product(DjangoObjectType):
    class Meta:
        model = models.Product
        interfaces = (graphene.relay.Node,)
        fields = ("id", "cost")

So that's really handy for querying. If you have custom properties on your models that return Money, you can easily declare the type on the graphene object and the resolver will Just Work (tm):

And lastly, to handle money as GraphQL input, it provides a MoneyInput type, which has a convenient .money method to access the input as a Money instance:

import graphene
from graphene_djmoney.schema import MoneyInput

from .. import models
from .types import Product


class UpdateProduct(graphene.Mutation):
    class Arguments:
        id = graphene.ID(required=True)
        cost = MoneyInput(required=True)

    success = graphene.Boolean(required=True)
    product = graphene.Field(Product)

    def mutate(root, info, id, cost):
        models.Product.objects.filter(id=id).update(
            cost=cost.money,
        )
        product = models.Product.objects.get(id=id)
        return UpdateProduct(product=product, success=True)

For more details, check out the test_app in the GitHub repository. If you have any trouble or suggestions for improvement, feel free to open an issue.

To install and use this, it's available on pypi:

pip install graphene-djmoney

Thanks for reading and enjoy!