Question

This seems like a bug but I just want to make sure I'm consuming the API properly.

It seems that support for django's modelform isn't supported on neo4django. Here's what I have:

Simple class:

from neo4django.db import models

class Person(models.NodeModel): name = models.StringProperty()

The modelform:

class PersonForm(forms.ModelForm): class Meta: model = Person

Will trigger exception:

'super' object has no attribute 'editable'

I posted details as an issue: https://github.com/scholrly/neo4django/issues/135

Because when Django goes to lookup field information using the model's _meta information, it finds a BoundProperty instead of a StringProperty or Property (which has a member called 'editable', but BoundProperty doesn't).

Is there a workaround, or is this an actual bug? Any ideas on how to fix the bug? I'm not familiar with the library codebase.

Thanks!

Was it helpful?

Solution

Below is a reasonable (and quick) workaround for anyone using neo4j with Django.

This solution requires that field names on the form have the exact same name as the attributes of the model.

Inherit the form from this class and set the model under the form class Meta class:

class NeoModelForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(NeoModelForm, self).__init__(*args, **kwargs)
        self._meta = getattr(self, 'Meta', None)
        if not self._meta:
            raise Exception('Missing Meta class on %s' % str(self.__class__.__name__))
        if not hasattr(self._meta, 'model'):
            raise Exception('Missing model on Meta class of %s' % str(self.__class__.__name__))

    def save(self, commit=True):
        if not self.is_valid():
            raise Exception('Failed to validate')
        instance = self._meta.model(**self.cleaned_data)
        if commit:
            instance.save()
        return instance

Now you can create a form class like this:

class PersonForm(NeoModelForm):
    name = forms.CharField(widget=forms.TextInput())
    class Meta:
        model = Person

And still be able to save a model instance from a valid form:

form = formclass(request.POST)
if form.is_valid():
    obj = form.save()

Plus the commit argument will give you the same solution as django's modelform class- but I didn't bother to implement to save_m2m functionality (which doesn't seem relevant for neo4j as a backend).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top