Django:将mixins用于常见的模型字段

时间:2014-02-16 22:10:41

标签: python django django-south mixins

我正在尝试创建代表数据库中常用字段的mixins。在此示例中,数据库表通常会跟踪创建记录的时间,创建记录的人员,编辑记录的时间以及编辑记录的人员。为此,我创建了以下mixins:

[项目] /libs/mixins/CreationAuditMixin.py:

from django.db import models

class CreationAuditMixin(models.Model):
    """ CreationAuditMixin documentation
    """
    created_at = models.DateTimeField(auto_now_add=True)
    created_by = models.CharField(max_length=255, blank=True, editable=False)

    class Meta:
        abstract = True

[项目] /libs/mixins/ModificationAuditMixin.py:

from django.db import models

class ModificationAuditMixin(models.Model):
    """ ModificationAuditMixin documentation
    """
    modified_at = models.DateTimeField(auto_now=True)
    modified_by = models.CharField(max_length=255, blank=True, editable=False)

    class Meta:
        abstract = True

[project] /libs/mixins/FullAuditMixin.py(仅为方便起见):

from django.db import models

from libs.mixins.audit import CreationAuditMixin, ModificationAuditMixin

class FullAuditMixin(models.Model, CreationAuditMixin, ModificationAuditMixin):

    class Meta:
        abstract = True

[项目] /libs/models/questions/Context.py:

from django.db import models

from libs.mixins.audit import FullAuditMixin, CreationAuditMixin, ModificationAuditMixin

_app_label = 'questions'
_db_table = '\".\"'.join((_app_label, 'context'))

class Context(models.Model, FullAuditMixin):
    """ Model representing a Context
    """
    _format_string = "{}: {}, {} - {}"

    name = models.CharField(max_length=255)
    description = models.CharField(max_length=2000)
    publish_start = models.DateTimeField()
    publish_end = models.DateTimeField()

    def __unicode__(self):
        """ Returns a unicode representation of the model
        """
        result = self._format_string.format(self.name, self.description, self.publish_start, self.publish_end)
        return result

    class Meta:
        app_label = _app_label
        db_table = _db_table

我可能会稍后将模型移动到他们特定的应用程序文件结构中,但是现在已经有了schema / app_label / db_table的手动配置,因此这种结构不会提供额外的配置。

尝试导入Context的任何内容(大多数管理命令,在这种情况下,尝试迁移)时收到以下错误:

./manage.py schemamigration questions --initial
Traceback (most recent call last):
  File "./manage.py", line 20, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 284, in execute
    self.validate()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 310, in validate
    num_errors = get_validation_errors(s, app)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/validation.py", line 34, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 196, in get_app_errors
    self._populate()
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 75, in _populate
    self.load_app(app_name, True)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 99, in load_app
    models = import_module('%s.models' % app_name)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 40, in import_module
    __import__(name)
  File "./apps/questions/models.py", line 1, in <module>
    from libs.models.questions import Context
  File "./libs/models/questions/Context.py", line 3, in <module>
    from libs.mixins.audit import FullAuditMixin, CreationAuditMixin, EditAuditMixin
  File "./libs/mixins/audit/FullAuditMixin.py", line 5, in <module>
    class FullAuditMixin(models.Model, CreationAuditMixin, EditAuditMixin):
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 79, in __new__
    new_class = super_new(cls, name, bases, {'__module__': module})
TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

当我构建这些mixins时,我已经咨询了Django: Creating a Mixin for Reusable Model Fieldshttp://www.djangocurrent.com/2011/05/django-aspect-oriented-models.html,我的方法是基于阅读这些。关于如何正确构造这些mixin的任何想法以及这个错误的原因将不胜感激。

1 个答案:

答案 0 :(得分:2)

上下文不应该继承自models.Model,因为它已经在mixins本身的继承链中。出于同样的原因,您可能还需要从FullAuditMixin中删除models.Model。