Skip to content

Commit

Permalink
add django admin register (#56)
Browse files Browse the repository at this point in the history
now it works the list view and the form view
  • Loading branch information
nossila authored Jun 24, 2021
1 parent 73796bb commit 9ca3eb3
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 14 deletions.
66 changes: 61 additions & 5 deletions django_neomodel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
from django.db.models import signals
from django.db.models.fields import BLANK_CHOICE_DASH
from django.conf import settings
from django.forms import fields
from django.forms import fields as form_fields
from django.db.models.options import Options
from django.core.exceptions import ValidationError

from neomodel import RequiredProperty, DeflateError, StructuredNode
from neomodel import RequiredProperty, DeflateError, StructuredNode, UniqueIdProperty
from neomodel.core import NodeMeta
from neomodel.match import NodeSet


__author__ = 'Robin Edwards'
Expand Down Expand Up @@ -39,17 +41,29 @@ class DjangoField(object):
concrete = True
editable = True
creation_counter = 0
unique = False
primary_key = False
auto_created = False

def __init__(self, prop, name):
self.prop = prop

self.name = name
self.remote_field = name
self.attname = name
self.verbose_name = name
self.help_text = getattr(prop, 'help_text', '')

if isinstance(prop, UniqueIdProperty):
# this seems that can be implemented in neomodel
# django-neomodel does have the needed code already but neomodel does not support
prop.primary_key = True

self.primary_key = getattr(prop, 'primary_key', False)
self.label = prop.label if prop.label else name

form_cls = getattr(prop, 'form_field_class', 'Field') # get field string
self.form_class = getattr(fields, form_cls, fields.CharField)
self.form_class = getattr(form_fields, form_cls, form_fields.CharField)

self._has_default = prop.has_default
self.required = prop.required
Expand Down Expand Up @@ -133,7 +147,42 @@ def get_choices(self, include_blank=True):
return first_choice + choices


class DjangoNode(StructuredNode):
class Query:
select_related = False
order_by = ['pk']


class NeoNodeSet(NodeSet):
query = Query()

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.model = self.source

def count(self):
return len(self)

def _clone(self):
return self


class NeoManager:
def __init__(self, model):
self.model = model

def get_queryset(self):
return NeoNodeSet(self.model)


class MetaClass(NodeMeta):
def __new__(cls, *args, **kwargs):
super_new = super().__new__
new_cls = super_new(cls, *args, **kwargs)
setattr(new_cls, "_default_manager", NeoManager(new_cls))
return new_cls


class DjangoNode(StructuredNode, metaclass=MetaClass):
__abstract_node__ = True

@classproperty
Expand All @@ -142,10 +191,13 @@ def _meta(self):
raise NotImplementedError('unique_together property not supported by neomodel')

opts = Options(self.Meta, app_label=self.Meta.app_label)
opts.contribute_to_class(self.__class__, self.__class__.__name__)
opts.contribute_to_class(self, self.__name__)

for key, prop in self.__all_properties__:
opts.add_field(DjangoField(prop, key), getattr(prop, 'private', False))
if getattr(prop, "primary_key", False):
self.pk = prop
self.pk.auto_created = True

return opts

Expand Down Expand Up @@ -178,6 +230,8 @@ def validate_unique(self, exclude):

# see if any nodes already exist with each property
for key in unique_props:
if key == 'pk' and getattr(self.__class__, key).auto_created:
continue
val = getattr(self.__class__, key).deflate(props[key])
node = cls.nodes.get_or_none(**{key: val})

Expand All @@ -204,3 +258,5 @@ def post_delete(self):
if getattr(settings, 'NEOMODEL_SIGNALS', True):
signals.post_delete.send(sender=self.__class__, instance=self)

def serializable_value(self, attr):
return str(getattr(self, attr))
4 changes: 4 additions & 0 deletions django_neomodel/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.contrib import admin

def register(model, model_admin):
admin.site.register([model], model_admin)
6 changes: 5 additions & 1 deletion tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',

# Third party
'django_neomodel',
Expand All @@ -69,6 +70,9 @@
"django.contrib.messages.middleware.MessageMiddleware",
]

STATIC_ROOT = "./static/"
STATIC_URL = '/static/'

DJANGO_SUPERUSER_PASSWORD = "1234"
DJANGO_SUPERUSER_EMAIL = "[email protected]"
DJANGO_SUPERUSER_USERNAME = "admin"
DJANGO_SUPERUSER_USERNAME = "admin"
19 changes: 14 additions & 5 deletions tests/someapp/admin.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
from django.contrib import admin
from django.contrib import admin as dj_admin
from django_neomodel import admin as neo_admin
from .models import Library, Book, Shelf

from .models import Library


@admin.register(Library)
class LibraryAdmin(admin.ModelAdmin):
class LibraryAdmin(dj_admin.ModelAdmin):
list_display = (
"id",
"name",
)
dj_admin.site.register(Library, LibraryAdmin)


class BookAdmin(dj_admin.ModelAdmin):
list_display = ("title", "created")
neo_admin.register(Book, BookAdmin)


class ShelfAdmin(dj_admin.ModelAdmin):
list_display = ("name",)
neo_admin.register(Shelf, ShelfAdmin)
18 changes: 16 additions & 2 deletions tests/someapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Meta:


class Book(DjangoNode):
uid = UniqueIdProperty()
uid = UniqueIdProperty(primary_key=True)
title = StringProperty(unique_index=True)
format = StringProperty(required=True) # check required field can be omitted on update
status = StringProperty(choices=(
Expand All @@ -24,4 +24,18 @@ class Book(DjangoNode):
created = DateTimeProperty(default=datetime.utcnow)

class Meta:
app_label = 'someapp'
app_label = "someapp"

def __str__(self):
return self.title


class Shelf(DjangoNode):
uid = UniqueIdProperty(primary_key=True)
name = StringProperty()

class Meta:
app_label = "someapp"

def __str__(self):
return self.name
4 changes: 3 additions & 1 deletion tests/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static


urlpatterns = [url(r"^admin/", admin.site.urls)]
urlpatterns = [url(r"^admin/", admin.site.urls)] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

0 comments on commit 9ca3eb3

Please sign in to comment.