neo4django mixin inheritance problems
Question: Considering [my previous
question](http://stackoverflow.com/questions/18849973/neo4django-multiple-
inheritance), I try to implement what I need.  
The following is the content of a django app models.py.

    
    
    from neo4django.db import models
    from neo4django.auth.models import User as AuthUser
    
    class MyManager(models.manager.NodeModelManager):
        def filterLocation(self,**kwargs):
            qs = self.get_query_set()
            if 'dist' in kwargs:
                qs = qs.filter(_where_dist=kwargs['dist'])
            elif 'prov' in kwargs:
                qs = qs.filter(_where_prov=kwargs['prov'])
            elif 'reg' in kwargs:
                qs = qs.filter(_where_reg=kwargs['reg'])
            return qs
    
    
    class MyMixin(object):
        _test = models.BooleanProperty(default=True)
        _where_dist = models.StringProperty(indexed=True)
        _where_prov = models.StringProperty(indexed=True)
        _where_reg = models.StringProperty(indexed=True)
    
        search = MyManager()
    
        class Meta:
            abstract = True
    
    class Activity(MyMixin,models.NodeModel):
        name = models.StringProperty()
    
    class User(MyMixin,AuthUser):
        info = models.StringProperty()
    

I have many problems. The first is the non-inheritance of MyMixin's
attributes:

    
    
    >>> joe=User.objects.create(username='joe') # OK!
    >>> joe
    <User: joe>
    >>> bill=User.objects.create(username='bill',_test=True)
    
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/manager.py", line 43, in create
        return self.get_query_set().create(**kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/query.py", line 1296, in create
        return super(NodeQuerySet, self).create(**kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/django/db/models/query.py", line 375, in create
        obj = self.model(**kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/base.py", line 141, in __init__
        super(NodeModel, self).__init__(*args, **kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/django/db/models/base.py", line 367, in __init__
        raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])
    TypeError: '_test' is an invalid keyword argument for this function
    

But also the create fails to set User's own attributes!

    
    
    >>> k=User.objects.create(username='kevin',info='The Best')
    
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/manager.py", line 43, in create
        return self.get_query_set().create(**kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/query.py", line 1296, in create
        return super(NodeQuerySet, self).create(**kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/django/db/models/query.py", line 375, in create
        obj = self.model(**kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/base.py", line 141, in __init__
        super(NodeModel, self).__init__(*args, **kwargs)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/django/db/models/base.py", line 367, in __init__
        raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])
    TypeError: 'info' is an invalid keyword argument for this function
    

None of the mixin or User class own attributes exist in User. If I derived in
reverse order:

    
    
    class User(AuthUser,MyMixin):  
    

Here they are present, but I don't think is a good practice, should not core
models go to the right? Anyway, as we see below, Activity does not have this
problem,  
like if AuthUser removed all attributes (intended behavior?).

While the alternative creation method works:

    
    
    >>> k=User(username='kevin',info='The Best')
    >>> k.save()
    >>> k
    <User: kevin>
    

But using the other Model, Activity, which inherits directly from
NodeModelManager  
(with User we have an intermediate parent AuthUser), things are better:

    
    
    >>> a=Activity.objects.create(name="AA")
    >>> a
    <Activity: Activity object>
    

Several tests made with a simple NodeModel inheritance were ok, the problems
arise with multiple inheritance and mixins.

Another problem, with my NodeModelManager:

    
    
    >>> User.search.filterLocation(dist="b")
    
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "/home/tonjo/prj/tuned_prj/tuned_django/myapp/models.py", line 6, in filterLocation
        qs = self.get_query_set()
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/manager.py", line 31, in get_query_
    set
        return NodeQuerySet(self.model)
      File "/home/tonjo/venv/tuned/local/lib/python2.7/site-packages/neo4django/db/models/query.py", line 1222, in __init__
        self._app_label = model._meta.app_label
    AttributeError: 'NoneType' object has no attribute '_meta'
    

This one is beyond my comprehension ;) MyManager worked well when in a
previous test I derived from a NodeModel's child, not from a mixin.


Answer: This is a pretty complicated question, but hopefully I can give you a pointer.

First- you need to understand that Django fields (and by extension neo4django
properties) cooperate with the class on which they're defined. That's why they
_only_ work when defined on a `Model` (or, in neo4django, a `NodeModel`).
There is no easy way to do multiple inheritance using Django models and
fields- my mixin suggestion from [your other
question](http://stackoverflow.com/questions/18849973/neo4django-multiple-
inheritance/) allows adding Python methods and attributes, but won't magically
make `Property` or `Field` play nicely with `object` as a parent class.

If you really want to avoid duplication of property definitions in this
situation, you have a few choices.

One is to use a shared super class- but in this case, you can't, since you
need to inherit from `neo4django.auth.models.User` with one of your classes.
This particular requirement will when neo4django supports Django 1.5+, which
allows swappable user models.

Most metaprogramming won't work easily, since Django and neo4django make use
of metaclasses. That said, I'm sure you could hack around this with a clever
class decorator or child metaclass- but I'm not sure you should from a sanity
standpoint :)

Let me know how it goes- maybe I'm missing an easier approach.

