
Security News
Crates.io Implements Trusted Publishing Support
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
graphene-django-flufy
Advanced tools
This library add some extra funcionalities to graphene-django to facilitate the graphql use without Relay, allow paginations and filtering integration and add some extra directives
This package builds on top of Graphene-Django-Extra
and it adds some extra functionalities to graphene-django to facilitate the graphql use without Relay:
NOTE: Subscription support still sits in moved to graphene-django-subscriptions. It may be moved later
For installing graphene-django-flufy, just run this command in your shell:
pip install graphene-django-flufy
Fields:
Mutations:
Types:
Paginations:
This is a basic example of graphene-django-extras package use. You can configure global params for DjangoListObjectType classes pagination definitions on settings.py like this:
GRAPHENE_DJANGO_FLUFY = {
'DEFAULT_PAGINATION_CLASS': 'graphene_django_flufy.paginations.LimitOffsetGraphqlPagination',
'DEFAULT_PAGE_SIZE': 20,
'MAX_PAGE_SIZE': 50,
'CACHE_ACTIVE': True,
'CACHE_TIMEOUT': 300 # seconds
}
from django.contrib.auth.models import User
from graphene_django_flufy import DjangoListObjectType, DjangoSerializerType, DjangoObjectType
from graphene_django_flufy.paginations import LimitOffsetGraphqlPagination
from .serializers import UserSerializer
class UserType(DjangoObjectType):
class Meta:
model = User
description = " Type definition for a single user "
filter_fields = {
"id": ("exact", ),
"first_name": ("icontains", "iexact"),
"last_name": ("icontains", "iexact"),
"username": ("icontains", "iexact"),
"email": ("icontains", "iexact"),
"is_staff": ("exact", ),
}
class UserListType(DjangoListObjectType):
class Meta:
description = " Type definition for user list "
model = User
pagination = LimitOffsetGraphqlPagination(default_limit=25, ordering="-username") # ordering can be: string, tuple or list
class UserModelType(DjangoSerializerType):
""" With this type definition it't necessary a mutation definition for user's model """
class Meta:
description = " User model type definition "
serializer_class = UserSerializer
pagination = LimitOffsetGraphqlPagination(default_limit=25, ordering="-username") # ordering can be: string, tuple or list
filter_fields = {
"id": ("exact", ),
"first_name": ("icontains", "iexact"),
"last_name": ("icontains", "iexact"),
"username": ("icontains", "iexact"),
"email": ("icontains", "iexact"),
"is_staff": ("exact", ),
}
from graphene_django_flufy import DjangoInputObjectType
class UserInput(DjangoInputObjectType):
class Meta:
description = " User InputType definition to use as input on an Arguments class on traditional Mutations "
model = User
import graphene
from graphene_django_flufy import DjangoSerializerMutation
from .serializers import UserSerializer
from .types import UserType
from .input_types import UserInputType
class UserSerializerMutation(DjangoSerializerMutation):
"""
DjangoSerializerMutation auto implement Create, Delete and Update functions
"""
class Meta:
description = " DRF serializer based Mutation for Users "
serializer_class = UserSerializer
class UserMutation(graphene.Mutation):
"""
On traditional mutation classes definition you must implement the mutate function
"""
user = graphene.Field(UserType, required=False)
class Arguments:
new_user = graphene.Argument(UserInput)
class Meta:
description = " Graphene traditional mutation for Users "
@classmethod
def mutate(cls, root, info, *args, **kwargs):
...
import graphene
from graphene_django_flufy import DjangoObjectField, DjangoListObjectField, DjangoFilterPaginateListField,
DjangoFilterListField, LimitOffsetGraphqlPagination
from .types import UserType, UserListType, UserModelType
from .mutations import UserMutation, UserSerializerMutation
class Queries(graphene.ObjectType):
# Possible User list queries definitions
users = DjangoListObjectField(UserListType, description='All Users query')
users1 = DjangoFilterPaginateListField(UserType, pagination=LimitOffsetGraphqlPagination())
users2 = DjangoFilterListField(UserType)
users3 = DjangoListObjectField(UserListType, filterset_class=UserFilter, description='All Users query')
# Defining a query for a single user
# The DjangoObjectField have a ID type input field, that allow filter by id and is't necessary to define resolve function
user = DjangoObjectField(UserType, description='Single User query')
# Another way to define a query to single user
user1 = UserListType.RetrieveField(description='User List with pagination and filtering')
# Exist two ways to define single or list user queries with DjangoSerializerType
user_retrieve1, user_list1 = UserModelType.QueryFields(
description='Some description message for both queries',
deprecation_reason='Some deprecation message for both queries'
)
user_retrieve2 = UserModelType.RetrieveField(
description='Some description message for retrieve query',
deprecation_reason='Some deprecation message for retrieve query'
)
user_list2 = UserModelType.ListField(
description='Some description message for list query',
deprecation_reason='Some deprecation message for list query'
)
class Mutations(graphene.ObjectType):
user_create = UserSerializerMutation.CreateField(deprecation_reason='Some one deprecation message')
user_delete = UserSerializerMutation.DeleteField()
user_update = UserSerializerMutation.UpdateField()
# Exist two ways to define mutations with DjangoSerializerType
user_create1, user_delete1, user_update1 = UserModelType.MutationFields(
description='Some description message for create, delete and update mutations',
deprecation_reason='Some deprecation message for create, delete and update mutations'
)
user_create2 = UserModelType.CreateField(description='Description message for create')
user_delete2 = UserModelType.DeleteField(description='Description message for delete')
user_update2 = UserModelType.UpdateField(description='Description message for update')
traditional_user_mutation = UserMutation.Field()
For use Directives you must follow two simple steps:
# settings.py
GRAPHENE = {
'SCHEMA_INDENT': 4,
'MIDDLEWARE': [
'graphene_django_flufy.ExtraGraphQLDirectiveMiddleware'
]
}
# schema.py
from graphene_django_flufy import all_directives
schema = graphene.Schema(
query=RootQuery,
mutation=RootMutation,
directives=all_directives
)
NOTE: Date directive depends on dateutil module, so if you do not have installed it, this directive will not be available. You can install dateutil module manually:
pip install python-dateutil
or like this:
pip install graphene_django_flufy[date]
That's all !!!
{
allUsers(username_Icontains:"john"){
results(limit:5, offset:5){
id
username
firstName
lastName
}
totalCount
}
allUsers1(lastName_Iexact:"Doe", limit:5, offset:0){
id
username
firstName
lastName
}
allUsers2(firstName_Icontains: "J"){
id
username
firstName
lastName
}
user(id:2){
id
username
firstName
}
user1(id:2){
id
username
firstName
}
}
mutation{
userCreate(newUser:{username:"test", password:"test*123"}){
user{
id
username
firstName
lastName
}
ok
errors{
field
messages
}
}
userDelete(id:1){
ok
errors{
field
messages
}
}
userUpdate(newUser:{id:1, username:"John"}){
user{
id
username
}
ok
errors{
field
messages
}
}
}
Let's suppose that we have this query:
query{
allUsers{
result{
id
firstName
lastName
dateJoined
lastLogin
}
}
}
And return this data:
{
"data": {
"allUsers": {
"results": [
{
"id": "1",
"firstName": "JOHN",
"lastName": "",
"dateJoined": "2017-06-20 09:40:30",
"lastLogin": "2017-08-05 21:05:02"
},
{
"id": "2",
"firstName": "Golden",
"lastName": "GATE",
"dateJoined": "2017-01-02 20:36:45",
"lastLogin": "2017-06-20 10:15:31"
},
{
"id": "3",
"firstName": "Nike",
"lastName": "just do it!",
"dateJoined": "2017-08-30 16:05:20",
"lastLogin": "2017-12-05 09:23:09"
}
]
}
}
}
As we see, some data it's missing or just not have the format that we like it, so let's go to format the output data that we desired:
query{
allUsers{
result{
id
firstName @capitalize
lastName @default(to: "Doe") @title_case
dateJoined @date(format: "DD MMM YYYY HH:mm:SS")
lastLogin @date(format: "time ago")
}
}
}
And we get this output data:
{
"data": {
"allUsers": {
"results": [
{
"id": "1",
"firstName": "John",
"lastName": "Doe",
"dateJoined": "20 Jun 2017 09:40:30",
"lastLogin": "4 months, 12 days, 15 hours, 27 minutes and 58 seconds ago"
},
{
"id": "2",
"firstName": "Golden",
"lastName": "Gate",
"dateJoined": "02 Jan 2017 20:36:45",
"lastLogin": "5 months, 28 days, 2 hours, 17 minutes and 53 seconds ago"
},
{
"id": "3",
"firstName": "Nike",
"lastName": "Just Do It!",
"dateJoined": "30 Aug 2017 16:05:20",
"lastLogin": "13 days, 3 hours, 10 minutes and 31 seconds ago"
}
]
}
}
}
As we see, the directives are an easy way to format output data on queries, and it's can be put together like a chain.
List of possible date's tokens: "YYYY", "YY", "WW", "W", "DD", "DDDD", "d", "ddd", "dddd", "MM", "MMM", "MMMM", "HH", "hh", "mm", "ss", "A", "ZZ", "z".
You can use this shortcuts too:
1. Update dependencies
2. Upgrade graphene-django dependency to version > 3.
FAQs
This library add some extra funcionalities to graphene-django to facilitate the graphql use without Relay, allow paginations and filtering integration and add some extra directives
We found that graphene-django-flufy 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.
Security News
Crates.io adds Trusted Publishing support, enabling secure GitHub Actions-based crate releases without long-lived API tokens.
Research
/Security News
Undocumented protestware found in 28 npm packages disrupts UI for Russian-language users visiting Russian and Belarusian domains.
Research
/Security News
North Korean threat actors deploy 67 malicious npm packages using the newly discovered XORIndex malware loader.