Django中的通用一对一关系


问题内容

我需要建立一对一关系,该关系也必须是通用的。也许您可以建议我一个更好的设计。到目前为止,我提出了以下模型

class Event(models.Model):
    # skip event related fields...
    content_type      = models.ForeignKey(ContentType)
    object_id         = models.PositiveIntegerField()
    content_object    = generic.GenericForeignKey('content_type', 'object_id')

    class Meta:
        unique_together   = ('content_type', 'object_id')

class Action1(models.Model):
    # skip action1 related fields...
    events = generic.GenericRelation(Event, content_type_field='content_type', object_id_field='object_id')

    @property
    def event(self):
        return self.events.get() # <<<<<< Is this reasonable?

class Action2(models.Model):...

在事件列表的Django
Admin中,我想收集所有操作,然后从那里转到操作的管理页面。是否可以避免event在动作模型中创建属性?有更好的解决方案吗?最好将字段events和属性组合event在一个定义中。我正在使用的项目使用Django
1.1


问题答案:

我最近遇到了这个问题。您所做的一切都很好,但是您可以通过创建一个可以透明地逆转关系的mixin将其概括起来:

class Event(models.Model):
    content_type      = models.ForeignKey(ContentType)
    object_id         = models.PositiveIntegerField()
    content_object    = generic.GenericForeignKey('content_type', 'object_id')

    class Meta:
        unique_together   = ('content_type', 'object_id')

class EventMixin(object):
     @property
     def get_event(self):
         ctype = ContentType.objects.get_for_model(self.__class__)
         try:
             event = Event.objects.get(content_type__pk = ctype.id, object_id=self.id)
         except:
            return None 
         return event

class Action1(EventMixin, models.Model):
    # Don't need to mess up the models fields (make sure the mixing it placed before models.Model)
    ...

action = Action1.object.get(id=1)
event = action.get_event

您可能也想向反向关系添加缓存