
Research
Security News
The Landscape of Malicious Open Source Packages: 2025 Mid‑Year Threat Report
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
django-simple-graphql
Advanced tools
A stupid simple GraphQL setup for Django
This project is still a WIP and will receive breaking changes
TODO: Improve the documentation
getModelName
and listModelName
queriesGraphQL
meta class to the model classfilters
: A django-filter
compatible set of filters supported on the
model's QuerySet. List or a Dictionary.exclude_fields
: A list of field names to exclude from the schemasearch_fields
: A list of fields to perform search onordering_fields
: A list of fields that can be used to order resultsdefault_ordering
: What ordering to use if none was specifiedgraphql_node_name
field to model classesgraphql_id
property to models, which can be used to retrieve the
Global ID of a model instance.Steps 1-3 are setup for graphene-django
.
See https://docs.graphene-python.org/projects/django/en/latest/installation/ for
more details.
If you are already using graphene-django
, you can skip to step 4.
graphene-django
to your INSTALLED_APPS
:
INSTALLED_APPS = [
# ...
"django.contrib.staticfiles", # Required for GraphiQL
"graphene_django",
]
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
urlpatterns = [
# ...
path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))),
]
schema.py
) and configure it to Graphene:
# settings.py
GRAPHENE = {
"SCHEMA": "myapp.shcema.schema",
}
# schema.py
from simple_graphql.django import Schema
schema = Schema()
By default, all model classes registered to the schema will get a query for fetching a single object by ID as well as a list query.
For the sake of an example, let's say we have the following model declaration:
from django.db import models
from myapp.schema import schema
@schema.graphql_model()
class Person(models.Model):
first_name = models.TextField()
last_name = models.TextField()
The graphql_model
decorator will add the model to our GraphQL schema builder,
which will build it into the following schema (relay schema omitted):
type Person implements Node {
id: ID!
lastName: String!
firstName: String!
}
type Query {
getPerson(id: ID!): Person
listPerson(after: String, before: String, first: Int, last: Int, offset: Int): PersonConnection
}
For a more complete example of the generated schema, see example/schema.graphql
TODO
There's two ways models can be added to the schema
from django.db import models
from myapp.schema import schema
@schema.graphql_model()
class Person(models.Model):
first_name = models.TextField()
last_name = models.TextField()
from django.contrib.auth import get_user_model
from myapp.schema import schema
User = get_user_model()
schema.register_model(User)
Model specific schemas can be configured either with a metaclass or passed in as a parameter. A base configuration also is present regardless of custom declarations.
If multiple configurations are present, they will be merged in the following precedence:
Where lower number means higher priority.
from django.db import models
from myapp.schema import schema
@schema.graphql_model()
class Person(models.Model):
first_name = models.TextField()
last_name = models.TextField()
credit_card_number = models.TextField()
parent = models.ForeignKey("self", on_delete=models.SET_NULL)
class GraphQL:
exclude_fields = ["credit_card_number"]
ordering_fields = ["first_name", "last_name"]
default_ordering = ["first_name"]
search_fields = ["first_name", "last_name"]
filters = ["parent"]
@staticmethod
def get_queryset(queryset: QuerySet["Person"], info: Any):
if info.context.user.is_superuser:
return queryset
return queryset.none()
from django.db import models
from myapp.schema import schema
class PersonGraphQLConfig:
exclude_fields = ["credit_card_number"]
ordering_fields = ["first_name", "last_name"]
default_ordering = ["first_name"]
search_fields = ["first_name", "last_name"]
filters = ["parent"]
@schema.graphql_model(PersonGraphQLConfig)
class Person(models.Model):
first_name = models.TextField()
last_name = models.TextField()
credit_card_number = models.TextField()
parent = models.ForeignKey("self", on_delete=models.SET_NULL)
from django.db import models
from simple_graphql.django import ModelSchemaConfig
from myapp.schema import schema
@schema.graphql_model(ModelSchemaConfig(
exclude_fields=["credit_card_number"],
ordering_fields=["first_name", "last_name"],
default_ordering=["first_name"],
search_fields=["first_name", "last_name"],
filters=["parent"],
))
class Person(models.Model):
first_name = models.TextField()
last_name = models.TextField()
credit_card_number = models.TextField()
parent = models.ForeignKey("self", on_delete=models.SET_NULL)
from django.contrib.auth import get_user_model
from simple_graphql.django import ModelSchemaConfig
from myapp.schema import schema
User = get_user_model()
# Could also use a class here just like with the decorator
schema.register_model(User, ModelSchemaConfig(
exclude_fields=["password"],
))
FAQs
A stupid simple GraphQL setup for Django
We found that django-simple-graphql demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A look at the top trends in how threat actors are weaponizing open source packages to deliver malware and persist across the software supply chain.
Security News
ESLint now supports HTML linting with 48 new rules, expanding its language plugin system to cover more of the modern web development stack.
Security News
CISA is discontinuing official RSS support for KEV and cybersecurity alerts, shifting updates to email and social media, disrupting automation workflows.