2011-10-20 79 views
18

我需要建立一對一的關係,它也必須是通用的。也許你可以給我一個更好的設計建議。到目前爲止,我想出了以下型號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管理在事件列表我要收集所有的行動,並從那裏我想要去管理頁面進行操作。是否有可能避免在動作模型中創建event屬性?有更好的解決方案嗎?在單個定義中將字段events和屬性event組合起來會很好。我正在使用的項目使用Django 1.1

+0

如果您確實想避免'events',則需要手動將查詢實現到'Event'表,如下所示。我仍然希望將'events'作爲GenericRelation,然後在'event'屬性中使用'self.events.first()'。此外,這將更容易讓您在未來消除獨特的限制。 – alexcasalboni

回答

14

我最近是came across this problem。您所做的一切是好的,但你可以通過創建逆轉透明的關係混入概括它一點點:

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 

你可能想緩存添加到反關係太

+0

它的功能很好,但它不具備這樣的功能:'Action.objects.select_related('event')' – ramusus

+0

我不喜歡這個解決方案 - >即使您需要使用GenericRelation, 'self.events.get()'或'self.events.first()' – alexcasalboni

+0

與上面的註釋相同。你最初使用'GenericRelation'的方法要好得多。 –