neo4django混入继承问题(neo4django mixin inheritance prob

2019-10-18 15:57发布

考虑到我刚才的问题 ,我尝试实现我需要什么。
下面是一个Django应用程序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()

我有很多问题。 首先是MyMixin的属性的非继承:

>>> 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

但也创造未能设置用户自身的属性!

>>> 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

该混入或User类自身的属性没有在用户存在。 如果我以相反的顺序得到:

class User(AuthUser,MyMixin):  

在这里,他们都存在,但我不认为这是一个很好的做法,不应核心型号到正确的? 无论如何,正如我们下面看到的,活动不存在这个问题,
就像如果为AuthUser移除所有属性(预期行为?)。

虽然另类创建方法的工作原理:

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

但使用其他模型,活动,直接从NodeModelManager继承
(与用户,我们有一个中间父为AuthUser),事情是更好:

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

用一个简单的节点模型继承进行了一些测试是OK,多重继承和混入出现的问题。

还有一个问题,我的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'

这一个是我无法理解;)MyManager运作良好时,在以前的测试我从一个节点模型的孩子得到的,而不是从一个mixin。

Answer 1:

这是一个非常复杂的问题,但我希望我可以给你一个指针。

第一代你要明白,Django的领域(通过扩展neo4django属性)与他们定义上的类合作。 这就是为什么他们只能在规定的工作时, Model (或在neo4django,一个NodeModel )。 有没有简单的方法使用Django模型做多继承和fields-我混入建议您的其他问题允许添加Python方法和属性,但不会神奇地让PropertyField发挥很好地与object的父类。

如果你真的想避免这种情况的属性定义重复,你有几个选择。

一种方法是使用一个共享的超类-但在这种情况下,你不能,因为你需要从继承neo4django.auth.models.User与类之一。 当neo4django支援Django 1.5 +,它允许用户热插拔机型此特殊要求的意愿。

大多数的元编程不会轻易成功,因为Django和neo4django使用元类的。 这就是说,我相信你能解决这个破解一个聪明类装饰或儿童metaclass-,但我不知道你从理智的角度来看应该:)

让我知道它是如何goes-也许我缺少一个更简单的方法。



文章来源: neo4django mixin inheritance problems