Я хочу, чтобы некоторые из моих моделей Django имели свойство «owner». Возможно, мне придется изменить или увеличить логику позже, и логика будет использоваться повторно во многих классах. Поэтому я хотел бы просто наследовать класс Owned
, который позволяет мне хранить пользователя, создавшего класс. Я еще не пытаюсь заполнить поле, мне просто нужно, чтобы он существовал.Подкласс Django ModelBase (метакласс для моделей Django)
Сначала я попытался это:
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 Reverse Accessor Clashes
Похоже, что этот собственности «владелец» должен иметь другое «related_name» в подклассах класса Owned
.
Так что я попытался это:
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
я получаю owner
свойство с именем соответствующего *class_name*_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'
Что я делаю неправильно?