Generic one-to-one relation in Django

后端 未结 2 1575
北荒
北荒 2021-01-07 18:07

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 Eve         


        
相关标签:
2条回答
  • 2021-01-07 18:30

    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)
        ...
    

    and

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

    You might want to add caching to the reverse relationship too

    0 讨论(0)
  • 2021-01-07 18:32

    Use .get() return raise if object doesn't exist, .first() return None if object doesn't exist.

    Name events_relation is an elegant way to differentiate event from events.

    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') # Important
    
    class Action1(models.Model):
        events_relation = generic.GenericRelation(Event)
    
        @property
        def event(self):
            # Return the object in exists
            # else None 
            return self.events_relation.first()
    
    0 讨论(0)
提交回复
热议问题