Django中的通用一对一关系 [英] Generic one-to-one relation in Django

查看:155
本文介绍了Django中的通用一对一关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要设置一对一的关系,也必须是通用的。可能你可以建议我一个更好的设计。到目前为止,我想到了以下模型:

I need to set up one-to-one relation which must also be generic. May be you can advice me a better design. So far I came up to the following models

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管理员在事件列表中我想收集所有的操作,从那里我想去管理页面的操作。是否可以避免在动作模型中创建事件属性?有更好的解决方案吗?在单个定义中组合字段事件和属性事件将是很好的。我正在使用的项目使用Django 1.1

In Django Admin in event list I want to collect all actions, and from there I want go to admin pages for actions. Is it possible to avoid creating event property in the action models? Is there a better solution? It would be nice to combine the field events and the property event in a single definition. The project I am working with uses Django 1.1

推荐答案

我最近遇到这个问题。你所做的一切都很好,但是您可以通过创建一个透明地反转关系的mixin来更广泛地使用它:

I recently came across this problem. What you have done is fine, but you can generalise it a little bit more by creating a mixin that reverses the relationship transparently:

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

您可能希望将缓存添加到反向关系中

You might want to add caching to the reverse relationship too

这篇关于Django中的通用一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆