【发布时间】:2016-02-21 01:41:48
【问题描述】:
我希望我的一些 Django 模型具有“所有者”属性。稍后我可能需要更改或扩充逻辑,并且该逻辑在许多类中被重用。所以我想从一个Owned 类继承,让我存储创建该类的用户。我还没有尝试填充该字段,我只是需要它存在。
首先我尝试了这个:
from django.db import models
from django.contrib.auth.models import User
class Owned(models.Model):
owner = models.ForeignKey(User, related_name='owner')
class Meta:
abstract = True
但是当我在几个子类中从 Owned 继承时,我得到了一个 Django 反向访问器错误:Django Reverse Accessor Clashes
看起来这个“所有者”属性需要在 Owned 类的子类中具有不同的“related_name”。
所以我尝试了这个:
from django.db import models
from django.db.models.base import ModelBase
from django.contrib.auth.models import User
class _OwnedMeta(ModelBase):
'''
Should makes "Owned" class below work.
Gets around problem with reverse accessor clashes:
'''
def __init__(cls, name, bases, dct):
related_name = '{}_owner'.format(name)
dct['owner'] = models.ForeignKey(User, related_name=related_name)
super(_OwnedMeta, cls).__init__(name, bases, dct)
class Owned(models.Model):
'''
Instances get an "owner" attribute
that is a foreign key to '<class_name>_owner'
'''
__metaclass__ = _OwnedMeta
owner = models.ForeignKey(User, related_name='owner')
class Meta:
abstract = True
这个想法是,当我将Owned 子类化时,我将获得一个具有相关名称*class_name*_owner 的owner 属性。
像这样:
Class Subclass(Owned):
pass
instance = Subclass()
现在,如果这可行,instance.subclassed 将是 Django User 模型的外键,related_name 将是“Subclass_owner”。
但它不起作用。这是错误消息的摘录:
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/base.py", line 297, in add_to_class
value.contribute_to_class(cls, name)
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1588, in contribute_to_class
super(ForeignObject, self).contribute_to_class(cls, name, virtual_only=virtual_only)
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 272, in contribute_to_class
add_lazy_relation(cls, self, other, resolve_related_class)
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 84, in add_lazy_relation
operation(field, model, cls)
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 271, in resolve_related_class
field.do_related_class(model, cls)
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 307, in do_related_class
self.set_attributes_from_rel()
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 304, in set_attributes_from_rel
self.rel.set_field_name()
File "/Users/maxwellheiber/dev/dc/lib/python2.7/site-packages/django/db/models/fields/related.py", line 1259, in set_field_name
self.field_name = self.field_name or self.to._meta.pk.name
AttributeError: 'NoneType' object has no attribute 'name'
我做错了什么?
【问题讨论】:
标签: django python-2.7 django-models metaclass