1

I have a model (Booking) with a OneToOneField (Thread) that subsequently has a ForeignKey relationship (Message). I would like to show a list of messages on the Booking admin, but with the Thread model in between it appears that this is hard/not possible?

Class Booking(Model):
    ...
    thread = models.OneToOneField('user_messages.Thread', verbose_name='thread')

class Thread(Model):
    ...

class Message(Model):
    thread = models.ForeignKey(Thread, related_name="messages")

Is there a way I can set up my BookingAdmin with an inline that can display messages (spanning across the thread relationship)? Something like:

class MessageInline(TabularInline):
    model = Message
    fk_name = '???'

class BookingAdmin(ModelAdmin):
    inlines = [MessageInline, ]

I'm happy to override the way the Inlines work if that's the best way, but I'm not sure where to tackle that. It looks like overriding *get_formset* might do the trick?

Rog
  • 4,075
  • 2
  • 24
  • 35
  • maybe this helps: http://stackoverflow.com/questions/3681258/nested-inlines-in-the-django-admin or this: http://stackoverflow.com/questions/702637/django-admin-inline-inlines-or-three-model-editing-at-once I know these links have foreign keys and not oneotoonefield like yours, but the answer should be the same because, if i'm not wrong, `OneToOneField` is the same as `ForeignKey` but with some constraints that make each "link" (relation) to be unique – marianobianchi Jul 07 '12 at 03:49
  • @marianobianchi Good suggestion, I think nested inlines try to solve too much of the problem, but the approach is right. I've come up with something (answer below) that overrides just enough. – Rog Jul 07 '12 at 04:11

1 Answers1

0

This isn't completely tested yet, but appears to work. The solution is to have an inline and formset with hooks to replace the booking with the attached thread...

class BookingMessageFormset(BaseInlineFormSet):
    '''Given a Booking instance, divert to its Thread'''
    def __init__(self, *args, **kwargs):
        if 'instance' in kwargs:
            kwargs['instance'] = kwargs['instance'].thread
        else:
            raise Exception()  # TODO Not sure if/when this happens
        BaseInlineFormSet.__init__(self, *args, **kwargs)

class MessageInline(admin.TabularInline):
    model = Message
    formset = BookingMessageFormset

    def __init__(self, parent_model, admin_site):
        '''Override parent_model'''
        super(MessageInline, self).__init__(Thread, admin_site)
Rog
  • 4,075
  • 2
  • 24
  • 35