Django: создание миксина для многоразовых полей - PullRequest
18 голосов
/ 16 мая 2011

У меня есть несколько полей, которые я хочу добавить в большинство моделей моего проекта. Например, эти поля являются «полями отслеживания», такими как дата создания, дата обновления и «активный» флаг. Я пытаюсь создать Mixin, который я мог бы добавить к каждому классу модели, который позволил бы мне добавить эти дополнительные поля через множественное наследование. Однако, когда создается экземпляр объекта, кажется, что мои поля модели, которые были добавлены через Mixin, отображаются как методы объекта, а не как поля базы данных.

In [18]: Blog.objects.all()[0].created
Out[18]: <django.db.models.fields.DateTimeField object at 0x10190efd0>

Вот как выглядят мои модели:

from django.db import models

class Blog(models.Model, TrackingFieldMixin):
    name = models.CharField(max_length=64)
    type = models....


class TrackingFieldsMixin():

    active = models.BooleanField(default=True, 
        help_text=_('Indicates whether or not this object has been deleted.'))
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

Так что, похоже, это не работает. Кто-нибудь знает, как я могу создать многоразовый миксин для общих полей модели, аналогичных приведенным выше? Есть ли недостаток в этом подходе?

Спасибо за помощь, Джо

Обновление: обратите внимание, что некоторые из моих моделей, в которых я планирую использовать миксин, используют модель MPTT, поэтому я не могу просто сделать свой трекинг Mixing в базовом классе и наследовать только от него.

class Post(MPTTModel, TrackingFieldMixin):
    post_name = models....
    post_type = models...

1 Ответ

25 голосов
/ 16 мая 2011

Абстрактные модели по-прежнему должны наследоваться от model.Model для корректной работы:

class TrackingFieldsMixin(models.Model):

Также вместо вашего active BooleanField я бы добавил deleted_on DateTimeField, чтобы вы могли записывать, когда запись была удалена. Затем вы можете просто добавить свойства в экземпляр, чтобы увидеть, активен ли он:

@property
def active(self):
    return self.deleted_on is None

и в запросах и / или настраиваемый менеджер :

Blog.objects.filter(deleted_on__isnull=True)
...