考虑到my previous question,我尝试实现我所需要的。
以下是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用户中不存在任何mixin或User类自己的属性。如果我以相反的顺序导出:
class User(AuthUser,MyMixin): 在这里他们都在场,但我不认为这是一个很好的做法,难道核心模式不应该走到正确的方向吗?总之,正如我们下面所看到的,活动没有这个问题,
就像如果AuthUser删除了所有属性(预期的行为?)。
当另一种创作方法起作用时:
>>> k=User(username='kevin',info='The Best')
>>> k.save()
>>> k
<User: kevin>但是使用另一个模型Activity,它直接从NodeModelManager继承
(对于用户来说,我们有一个中间父AuthUser),情况会更好:
>>> a=Activity.objects.create(name="AA")
>>> a
<Activity: Activity object>使用简单的NodeModel继承进行的几个测试都是正常的,多继承和混合会出现问题。
另一个问题是,我的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'在之前的测试中,我是从NodeModel的子级派生出来的,而不是从混合模型派生出来的。
发布于 2013-09-18 18:18:20
这是一个相当复杂的问题,但希望我能给你一个指针。
首先,您需要理解Django字段(以及扩展到neo4django属性)与定义它们的类协作。这就是为什么它们只在Model (或者在neo4django中是NodeModel)上定义时才能工作的原因。使用Django模型和字段进行多重继承并不容易--我来自your other question的混合建议允许添加Property方法和属性,但不能神奇地使Property或Field作为父类很好地处理object。
如果您真的希望在这种情况下避免属性定义的重复,那么您有几个选择。
一种是使用共享的超类--但在本例中,您不能这样做,因为您需要使用一个类从neo4django.auth.models.User继承。当neo4django支持Django 1.5+时,这一特殊需求就会出现,后者允许可交换的用户模型。
大多数元编程不容易工作,因为Django和neo4django使用元类。尽管如此,我确信你可以用一个聪明的类装饰师或儿童元类来解决这个问题--但我不确定你是否应该从理智的角度出发:)
告诉我事情进展如何-也许我错过了一个更简单的方法。
https://stackoverflow.com/questions/18878290
复制相似问题