diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/__pycache__/__init__.cpython-38.pyc b/app/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..af1b2ed Binary files /dev/null and b/app/__pycache__/__init__.cpython-38.pyc differ diff --git a/app/__pycache__/admin.cpython-38.pyc b/app/__pycache__/admin.cpython-38.pyc new file mode 100644 index 0000000..5f5fb66 Binary files /dev/null and b/app/__pycache__/admin.cpython-38.pyc differ diff --git a/app/__pycache__/api.cpython-38.pyc b/app/__pycache__/api.cpython-38.pyc new file mode 100644 index 0000000..4f65429 Binary files /dev/null and b/app/__pycache__/api.cpython-38.pyc differ diff --git a/app/__pycache__/apps.cpython-38.pyc b/app/__pycache__/apps.cpython-38.pyc new file mode 100644 index 0000000..19985c6 Binary files /dev/null and b/app/__pycache__/apps.cpython-38.pyc differ diff --git a/app/__pycache__/models.cpython-38.pyc b/app/__pycache__/models.cpython-38.pyc new file mode 100644 index 0000000..69eaa77 Binary files /dev/null and b/app/__pycache__/models.cpython-38.pyc differ diff --git a/app/__pycache__/urls.cpython-38.pyc b/app/__pycache__/urls.cpython-38.pyc new file mode 100644 index 0000000..d4d27cc Binary files /dev/null and b/app/__pycache__/urls.cpython-38.pyc differ diff --git a/app/__pycache__/views.cpython-38.pyc b/app/__pycache__/views.cpython-38.pyc new file mode 100644 index 0000000..29d9cf1 Binary files /dev/null and b/app/__pycache__/views.cpython-38.pyc differ diff --git a/app/admin.py b/app/admin.py new file mode 100644 index 0000000..44859db --- /dev/null +++ b/app/admin.py @@ -0,0 +1,12 @@ +from django.contrib import admin as dj_admin +from django_neomodel import admin as neo_admin +from .models import Person + + +class PersonAdmin(dj_admin.ModelAdmin): + list_display = ( + "id", + "name", + ) + +dj_admin.site.register(Person, PersonAdmin) diff --git a/app/api.py b/app/api.py new file mode 100644 index 0000000..793509a --- /dev/null +++ b/app/api.py @@ -0,0 +1,8 @@ +from ninja import NinjaAPI + +api = NinjaAPI() + + +@api.get("/add") +def add(request, a: int, b: int): + return {"result": a + b} diff --git a/app/apps.py b/app/apps.py new file mode 100644 index 0000000..ed327d2 --- /dev/null +++ b/app/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AppConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'app' diff --git a/app/migrations/__init__.py b/app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/migrations/__pycache__/__init__.cpython-38.pyc b/app/migrations/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..a249561 Binary files /dev/null and b/app/migrations/__pycache__/__init__.cpython-38.pyc differ diff --git a/app/models.py b/app/models.py new file mode 100644 index 0000000..1578425 --- /dev/null +++ b/app/models.py @@ -0,0 +1,41 @@ +# from django.db import models + +from neomodel import (StructuredNode, StringProperty, + IntegerProperty,UniqueIdProperty, + RelationshipTo,BooleanProperty, + DateTimeProperty) + + +# Create your models here. +class User(StructuredNode): + __abstract_node__ = True + uid = UniqueIdProperty() + SEXES = {'F': 'Female', 'M': 'Male', 'O': 'Other'} + first_name = StringProperty(unique_index=True) + last_name = StringProperty(unique_index=True) + sex = StringProperty(required=True, choices=SEXES) + is_admin= BooleanProperty(unique_index=False,default=None) + is_user = BooleanProperty(unique_index=False,default=None) + password = StringProperty() + created = DateTimeProperty(default_now=True) + + +class UserMixin(object): + name = StringProperty(unique_index=True) + password = StringProperty() + + +class City(StructuredNode): + code = StringProperty(unique_index=True, required=True) + name = StringProperty(index=True, default="city") + + +class Person(StructuredNode): + uid = UniqueIdProperty() + name = StringProperty(unique_index=True) + age = IntegerProperty(index=True, default=0) + + # Relations : + city = RelationshipTo(City, 'LIVES_IN') + friends = RelationshipTo('Person','FRIEND') + diff --git a/app/tests.py b/app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/app/urls.py b/app/urls.py new file mode 100644 index 0000000..d9b05af --- /dev/null +++ b/app/urls.py @@ -0,0 +1,14 @@ +from django.conf.urls import url +from .views import connectPaP,connectPaC,cityDetails,personDetails,getAllPersons,getAllCities +from django.urls import path +from .api import api + +urlpatterns = [ + path('person',personDetails), + path('getAllPersons',getAllPersons), + path('city',cityDetails), + path('getAllCities',getAllCities), + path('connectPaC',connectPaC), + path('connectPaP',connectPaP), + path("api/", api.urls), +] \ No newline at end of file diff --git a/app/views.py b/app/views.py new file mode 100644 index 0000000..0d682d9 --- /dev/null +++ b/app/views.py @@ -0,0 +1,200 @@ +from django.http import JsonResponse +from .models import Person,City +from django.views.decorators.csrf import csrf_exempt +import json + + +def getAllPersons(request): + if request.method == 'GET': + try: + persons = Person.nodes.all() + response = [] + for person in persons : + obj = { + "uid": person.uid, + "name": person.name, + "age": person.age, + } + response.append(obj) + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + +def getAllCities(request): + if request.method == 'GET': + try: + cities = City.nodes.all() + response = [] + for city in cities: + obj = { + "code": city.code, + "name": city.name, + } + response.append(obj) + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + +@csrf_exempt +def personDetails(request): + if request.method == 'GET': + # get one person by name + name = request.GET.get('name', ' ') + try: + person = Person.nodes.get(name=name) + response = { + "uid": person.uid, + "name": person.name, + "age": person.age, + } + return JsonResponse(response, safe=False) + except : + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + + if request.method == 'POST': + # create one person + json_data = json.loads(request.body) + name = json_data['name'] + age = int(json_data['age']) + try: + person = Person(name=name, age=age) + person.save() + response = { + "uid": person.uid, + } + return JsonResponse(response) + except : + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + + if request.method == 'PUT': + # update one person + json_data = json.loads(request.body) + name = json_data['name'] + age = int(json_data['age']) + uid = json_data['uid'] + try: + person = Person.nodes.get(uid=uid) + person.name = name + person.age = age + person.save() + response = { + "uid": person.uid, + "name": person.name, + "age": person.age, + } + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + + if request.method == 'DELETE': + # delete one person + json_data = json.loads(request.body) + uid = json_data['uid'] + try: + person = Person.nodes.get(uid=uid) + person.delete() + response = {"success": "Person deleted"} + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + +@csrf_exempt +def cityDetails(request): + if request.method == 'GET': + # get one city by name + name = request.GET.get('name', ' ') + try: + city = City.nodes.get(name=name) + response = { + "code": city.code, + "name": city.name, + } + return JsonResponse(response, safe=False) + except : + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + + if request.method == 'POST': + # create one city + json_data = json.loads(request.body) + name = json_data['name'] + code = json_data['code'] + try: + city = City(name=name, code=code) + city.save() + response = { + "code": city.code, + } + return JsonResponse(response) + except : + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + + if request.method == 'PUT': + # update one city + json_data = json.loads(request.body) + name = json_data['name'] + code = json_data['code'] + try: + city = City.nodes.get(code=code) + city.name = name + city.save() + response = { + "code": city.code, + "name": city.name, + } + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + + if request.method == 'DELETE': + # delete one city + json_data = json.loads(request.body) + code = json_data['code'] + try: + city = City.nodes.get(code=code) + city.delete() + response = {"success": "City deleted"} + return JsonResponse(response) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + +@csrf_exempt +def connectPaC(request): + if request.method == 'PUT': + json_data = json.loads(request.body) + uid = json_data['uid'] + code = json_data['code'] + try: + person = Person.nodes.get(uid=uid) + city = City.nodes.get(code=code) + res = person.city.connect(city) + response = {"result": res} + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) + +@csrf_exempt +def connectPaP(request): + if request.method == 'PUT': + json_data = json.loads(request.body) + uid1 = json_data['uid1'] + uid2 = json_data['uid2'] + try: + person1 = Person.nodes.get(uid=uid1) + person2 = Person.nodes.get(uid=uid2) + res = person1.friends.connect(person2) + response = {"result": res} + return JsonResponse(response, safe=False) + except: + response = {"error": "Error occurred"} + return JsonResponse(response, safe=False) \ No newline at end of file diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..ad8416f --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'neomodels.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/neomodels/__init__.py b/neomodels/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/neomodels/__pycache__/__init__.cpython-38.pyc b/neomodels/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000..a2c4573 Binary files /dev/null and b/neomodels/__pycache__/__init__.cpython-38.pyc differ diff --git a/neomodels/__pycache__/settings.cpython-38.pyc b/neomodels/__pycache__/settings.cpython-38.pyc new file mode 100644 index 0000000..84c4728 Binary files /dev/null and b/neomodels/__pycache__/settings.cpython-38.pyc differ diff --git a/neomodels/__pycache__/urls.cpython-38.pyc b/neomodels/__pycache__/urls.cpython-38.pyc new file mode 100644 index 0000000..c357b0d Binary files /dev/null and b/neomodels/__pycache__/urls.cpython-38.pyc differ diff --git a/neomodels/__pycache__/wsgi.cpython-38.pyc b/neomodels/__pycache__/wsgi.cpython-38.pyc new file mode 100644 index 0000000..54c58e5 Binary files /dev/null and b/neomodels/__pycache__/wsgi.cpython-38.pyc differ diff --git a/neomodels/asgi.py b/neomodels/asgi.py new file mode 100644 index 0000000..839f0c0 --- /dev/null +++ b/neomodels/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for neomodels project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'neomodels.settings') + +application = get_asgi_application() diff --git a/neomodels/settings.py b/neomodels/settings.py new file mode 100644 index 0000000..927c915 --- /dev/null +++ b/neomodels/settings.py @@ -0,0 +1,133 @@ +""" +Django settings for neomodels project. + +Generated by 'django-admin startproject' using Django 3.2.5. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.2/ref/settings/ +""" + +from pathlib import Path +import os +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-vxrr$h&uetw#g*q!kbm-2s$*#bvv)s!+d!w^pv03ril7$&3s4$' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] +NEOMODEL_NEO4J_BOLT_URL = os.environ.get('NEO4J_BOLT_URL','bolt://neo4j:123456@localhost:7687') + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django_neomodel', + 'app', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'neomodels.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'neomodels.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/3.2/ref/settings/#databases + +# DATABASES = { +# 'default': { +# 'ENGINE': 'django.db.backends.sqlite3', +# 'NAME': BASE_DIR / 'db.sqlite3', +# } +# } + + +# Password validation +# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.2/howto/static-files/ + +STATIC_URL = '/static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + + +NEOMODEL_SIGNALS = True +NEOMODEL_FORCE_TIMEZONE = False +NEOMODEL_ENCRYPTED_CONNECTION = True +NEOMODEL_MAX_POOL_SIZE = 50 \ No newline at end of file diff --git a/neomodels/urls.py b/neomodels/urls.py new file mode 100644 index 0000000..77e7662 --- /dev/null +++ b/neomodels/urls.py @@ -0,0 +1,22 @@ +"""neomodels URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path,include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('app.urls')), +] diff --git a/neomodels/wsgi.py b/neomodels/wsgi.py new file mode 100644 index 0000000..cbddfa0 --- /dev/null +++ b/neomodels/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for neomodels project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'neomodels.settings') + +application = get_wsgi_application()