DEV Community

HyperRedStart
HyperRedStart

Posted on

Mongodb + GraphQL + Django

Mongodb + GraphQL + Django

Mongodb installation

Mongodb Image

docker pull mongo
docker run --name mongodb mongo
docker ps
================================
CONTAINER ID        IMAGE               COMMAND                  CREATED      STATUS              PORTS                      NAMES
2fef936de7f9        mongo               "docker-entrypoint.s"    10 days ago  Up About an hour    0.0.0.0:27017->27017/tcp   mongodb
Enter fullscreen mode Exit fullscreen mode

Mongodb Compass

Mongodb Compass


Django Constructor

conda update conda
conda create --name NGDP python=3.6
activate NGDP
(NGDP) D:\NGDP>

conda install -y Django=3.1.2
conda install -y -c conda-forge django-cors-headers
conda install -y  -c conda-forge graphene-django
conda install -y  -c conda-forge graphene-mongo
conda install -y  -c conda-forge django-filter
conda install -y  -c conda-forge mongoengine
conda install -y  -c conda-forge mongomock
conda install -c conda-forge neo4jdjango
conda install pytest
conda install pytest-django

django-admin startproject ngdp
conda install pip
Enter fullscreen mode Exit fullscreen mode

Start Project

django-admin startproject shoesstore
cd shoesstore
django-admin startapp store
django-admin startapp shoes
Enter fullscreen mode Exit fullscreen mode

Start Programming (Backend)

Project Structure

shoesstore/settings.py

# 載入 mongodb 引擎
from mongoengine import connect

# 允許所有裝置連線
ALLOWED_HOSTS = ['*']

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 預載程式
    'graphene_django',
    'graphene_mongo',
    'store',
    'shoes'
]

# mongodb connection
_MONGODB_USER = ""
_MONGODB_PASSWD = ""
_MONGODB_HOST = "localhost"
_MONGODB_NAME = "shoesstore"
_MONGODB_PORT = 27017
_MONGODB_DATABASE_HOST = "mongodb://%s:%s@%s/%s" % (
    _MONGODB_USER,
    _MONGODB_PASSWD,
    _MONGODB_HOST,
    _MONGODB_NAME,
)

connect(_MONGODB_NAME, host=_MONGODB_HOST, port=_MONGODB_PORT)

# Graphql Schema
GRAPHENE = {"SCHEMA": "shoesstore.schema.schema"} 
Enter fullscreen mode Exit fullscreen mode

shoesstore/urls.py

# 增加 graphql 路徑,csrf_exempt 跨網站請求豁免
urlpatterns = [
    path('admin/', admin.site.urls),
    path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True)), name="graphql-query")
]
Enter fullscreen mode Exit fullscreen mode

Graphql

query ($name: String) {
  bikes(first:1, name_Istartswith: $name) {
    totalCount
    pageInfo {
      hasPreviousPage
      hasNextPage
    }
    edges {
      node {
        name
        brand
        year
        size
        wheelSize
        type
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
query {
  allCategories(first: 1, after: "opaqueCursor") {
    edges {
      node {
        name,
        ingredients {
          edges {
            node {
              name
            }
          }
        }
      }
    }
      pageInfo {
        hasNextPage
      }
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  shoes(first: 2) {
    totalCount
    pageInfo {
      startCursor
      hasNextPage
      hasPreviousPage
      endCursor
    }
    edges {
      cursor
      node {
        name
        brand
        model
        id
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
query ($name: String) {
  bikes(first:2, name_Istartswith: $name, after: "YXJyYXljb25uZWN0aW9uOjE=") {
    totalCount
    pageInfo {
      endCursor
      hasPreviousPage
      hasNextPage
    }
    edges {
      node {
        id
        name
        brand
        year
        size
        wheelSize
        type
      }
      cursor
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

React Native App

expo init ShoesStoreProjectR
Enter fullscreen mode Exit fullscreen mode

Discussion (5)

Collapse
shlokabhalgat profile image
shlokabhalgat

Hi, I have a collection in MongoDb(locahost). How should I proceed with connecting the collections data in django with graphql?

Collapse
hyperredstart profile image
HyperRedStart Author

Hi,

Step 1.

You need to create model for your collection .

from django.db import models
from mongoengine import Document
from mongoengine.fields import (
    FloatField,
    StringField,
    ListField,
    URLField,
    ObjectIdField,
)

# Create your models here.
class Shoes(Document):
    meta = {'collection' : 'shoes'}
    ID = ObjectIdField()
    name = StringField()
    brand = StringField()
    model = StringField()
    price = FloatField()
    img = URLField()
    color = ListField(StringField())
Enter fullscreen mode Exit fullscreen mode

Step 2.

Using graphene is a GraphQL API library for Python create a type for your collection.

import graphene
from graphene import relay
from graphene_mongo import MongoengineObjectType
from .models import Shoes

class Connection(graphene.Connection):
    class Meta:
        abstract = True

    total_count = graphene.Int()

    def resolve_total_count(self, info):
        return self.iterable.count()

class ShoesType(MongoengineObjectType):
    class Meta:
        model = Shoes
        interfaces = (relay.Node,)
        connection_class = Connection
        filter_fields = {
            'name': ['exact', 'icontains', 'istartswith']
        }
Enter fullscreen mode Exit fullscreen mode

Step 3.

Delcare your type for graphene schema.

import graphene
from graphene.relay import Node
from graphene_mongo.fields import MongoengineConnectionField
from shoes.models import Shoes
from store.models import Store
from shoes.types import ShoesType
from store.types import StoreType

class Mutations(graphene.ObjectType):
    pass

class Query(graphene.ObjectType):
    # node = Node.Field()
    stores = MongoengineConnectionField(StoreType)
    shoes = MongoengineConnectionField(ShoesType)
    shoes_list = graphene.List(ShoesType)

    def resolve_shoes_list(self, info):
        return Shoes.objects.all()


schema = graphene.Schema(query=Query, types=[StoreType, ShoesType])
Enter fullscreen mode Exit fullscreen mode

That's the roughly process of using graphql with mongodb thank you!

Collapse
shlokabhalgat profile image
shlokabhalgat

Thanks @hyperredstart ! I just had one more question-
Will Step 2 code be in schema.py or models.py?

Thread Thread
hyperredstart profile image
HyperRedStart Author

Hi @shlokabhalgat
Step 2 is separate from schema.py, As you wish you could place TypeObject code in the schema.py.

Thanks!

Thread Thread
shlokabhalgat profile image
shlokabhalgat

Thanks a lot @hyperredstart I was able to do it! Keep up the good work😁