Graphene-Django Filenaming Conventions

2019-08-20 08:27发布

问题:

I'm rebuilding a former Django REST API project as a GraphQL one. I now have queries & mutations working properly.

Most of my learning came from looking at existing Graphene-Django & Graphene-Python code samples. There seem to be a lot of inconsistencies amongst them.

In some it was suggested that the GraphQL queries should be placed in schema.py whereas the mutations should be placed in mutation.py.

What I'm thinking makes more sense is to instead have these two files hold their respective code: - queries.py - mutations.py

I'm relatively new to Django & Python though so want to be sure that I'm not violating any conventions.

Interested in your thoughts!

Robert

回答1:

There aren't any conventions yet, since GraphQL is a fairly new alternative method to REST. Thus, "conventions" are created at the moment we speak.

However, since schema is general-defined term you may rename it to queries.

This is my project structure:

django_proj/
    manage.py
    requirements.txt
    my_app/
        __init__.py
        migrations/
        admin.py
        schema/
            __init__.py
            schema.py     # holds the class Query. The GraphQL endpoints, if you like
            types.py      # holds the DjangoObjectType classes
            inputs.py     # holds the graphene.InputObjectType classes (for defining input to a query or mutation)
            mutations.py  # holds the mutations (what else?!)

So the schema.py (__init__) could be renamed to queries.py if you like. There is no much big difference between these two words.



回答2:

I liked nik_m's answer so much I wrote some code to generate the template structure from inside the Django shell. I want to enforce some consistency as I create these files over and over again. I'm putting the code here in case someone else finds it useful.

import os

from django.conf import settings


def schema_setup(app_name):
    """
    Sets up a default schema file structure.
    """
    SCHEMA_DIRECTORY_NAME = 'schema'
    app_directory = os.path.join(settings.PROJECT_DIR, app_name)
    if not os.path.exists(app_directory):
        raise Exception("Can't find app directory {}".format(app_directory))

    schema_directory = os.path.join(app_directory, SCHEMA_DIRECTORY_NAME)
    if os.path.exists(schema_directory):
        raise Exception("Schema directory {} already exists.".format(schema_directory))

    os.makedirs(schema_directory)
    mutation_class = "{}Mutation".format(app_name.title())
    query_class = "{}Query".format(app_name.title())

    init_txt = "from .mutations import {}\nfrom .queries import {}\n".format(mutation_class, query_class)
    fields_txt = "# Insert common fields here.\nimport graphene\n"
    inputs_txt = "# Insert graphene.InputObjectType classes.\nimport graphene\n"
    mutations_txt = "# Insert graphql mutations here.\nimport graphene\n\nclass {}(graphene.AbstractType):\n    pass\n".format(mutation_class)
    queries_txt = "# Insert graphql queries here.\nimport graphene\n\nclass {}(graphene.AbstractType):\n    pass\n".format(query_class)
    types_txt = "# Insert DjangoObjectType classes here.\nimport graphene\nfrom graphene_django.types import DjangoObjectType\n"

    for fname, file_text in [("__init__.py", init_txt),
                             ("fields.py", fields_txt),
                             ("inputs.py", inputs_txt),
                             ("mutations.py", mutations_txt),
                             ("queries.py", queries_txt),
                             ("types.py", types_txt),
                             ]:
        with open(os.path.join(schema_directory, fname), "w") as output_file:
            output_file.write(file_text)
        print("Created {}".format(fname))

From inside the Django shell, run like schema_setup("my_app")

Note:

  • This assumes you set PROJECT_DIR in your settings like PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
  • In your top level schema, import like from my_app.schema import MyAppQuery, MyAppMutation
  • I've gone back and forth on "query" vs. "queries" and "mutation" vs "mutations" -- as of this moment, the graphene documentation isn't consistent