Skip to content

Instantly share code, notes, and snippets.

@weilu
Last active December 8, 2021 19:13
Show Gist options
  • Save weilu/6ed34467c90b6457e1687ff542ae1ce2 to your computer and use it in GitHub Desktop.
Save weilu/6ed34467c90b6457e1687ff542ae1ce2 to your computer and use it in GitHub Desktop.
Offset based pagination with Django, graphene, Apollo and react
import ReactDOM from 'react-dom';
import React, { useState, useCallback, useEffect } from 'react';
import { useQuery } from '@apollo/client';
import { gql } from '@apollo/client';
const CASE_FIELDS = `
id
referralDate
caseNumber
`
const fetchQuery = gql`
query Records ($orderBy: String, $skip: Int, $take: Int) {
casesPaginated (orderBy: $orderBy, skip: $skip, take: $take) {
total
objects {
${CASE_FIELDS}
}
}
}
`
function App() {
const [rows, setRows] = useState([])
const [totalRowCount, setTotalRowCount] = useState(0)
const defaultVariables = {
orderBy: 'caseNumber',
skip: 0,
take: 50
}
const [variables, setVariables] = useState(defaultVariables)
const onData = useCallback((data) => {
const dataRows = data['casesPaginated']['objects']
setRows(dataRows)
setTotalRowCount(data[paginatedKey]['total'])
}, [])
const { loading, error, refetch } = useQuery(fetchQuery, {
variables,
onCompleted: onData,
})
// refetch on variable change, e.g. different page
useEffect(() => {
refetch(variables)
}, [variables, refetch])
if (loading) return 'loading...'
return (
<React.StrictMode>
<div>
Total number of records: {totalRowCount}
<ul>
{rows.map(r => (
<li>{r.id} {r.caseNumber} {r.referralDate}</li>
))}
</ul>
</div>
</React.StrictMode>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
import graphene
from graphene_django import DjangoObjectType
from .models import Case
class CaseType(DjangoObjectType):
class Meta:
model = Case
class PaginatedCaseType(graphene.ObjectType):
total = graphene.Int()
objects = graphene.List(CaseType)
class Query(graphene.ObjectType):
cases_paginated = graphene.Field(PaginatedCaseType,
order_by=graphene.String(),
skip=graphene.Int(),
take=graphene.Int())
def resolve_cases_paginated(root, info, order_by='-id', skip=0, take=100, **kwargs):
qs = Case.objects.order_by(order_by)
objects = qs[skip:skip+take]
return PaginatedCaseType(objects=objects, total=qs.count())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment