user1330974
user1330974

Reputation: 2614

Displaying many-to-many (with through) and self-referencing relationship in Django

I set up a self-referencing model in Django 1.5 like this:

RELATIONSHIP_PARENT = 1
RELATIONSHIP_BLOCKED = 2
RELATIONSHIP_STATUSES = (
    (RELATIONSHIP_PARENT, 'Parent'),
    (RELATIONSHIP_BLOCKED, 'Blocked'),
) 

class Message(models.Model):
    content = models.CharField("Content", max_length=160, db_index=True)
    relationships = models.ManyToManyField('self',
        through='Relationship',
        symmetrical=False,
        related_name='related_to')

class Relationship(models.Model):
    parent_message = models.ForeignKey(Message, related_name='parent_messages')
    child_message = models.ForeignKey(Message, related_name='child_messages')
    status = models.IntegerField(choices=RELATIONSHIP_STATUSES)

This is inspired by the post http://charlesleifer.com/blog/self-referencing-many-many-through where he describes "Asymmetrical Relationships - the Twitter model" (my goal is to create parent-child relationship between messages, but that is probably an irrelevant information for this question). I was trying to configure the Django admin page to show Relationship information under Message section. I try to follow what I seem to be the closest example in Django documentation as shown below

from django.contrib import admin
from demo.models import Message, Relationship

class RelationshipInline(admin.TabularInline):
    model = Relationship
    extra = 1

class MessageAdmin(admin.ModelAdmin):
    inlines = (RelationshipInline,)

admin.site.register(Message, MessageAdmin)
admin.site.register(Relationship)

But I get error like:

Exception at /admin/
<class 'demo.models.Relationship'> has more than 1 ForeignKey to <class 'demo.models.Message'>

I know my case is slightly different from Django documentation's example in that I have a self-referencing model. I would like to know if there's a way to display a particular message's relationships (say its current children and parents) in one view/page via admin console. If so, could someone please show me how to do it? I'm new to Django and still learning, so apology if this question is too naive. Thank you.

Upvotes: 5

Views: 3138

Answers (2)

Victor Castillo Torres
Victor Castillo Torres

Reputation: 10811

As the doc says

Your intermediate model must contain one - and only one - foreign key to the target model (this would be Message in our example). If you have more than one foreign key, a validation error will be raised.

Upvotes: 0

karthikr
karthikr

Reputation: 99660

Try this

class RelationshipInline(admin.TabularInline):
    model = Relationship
    extra = 1
    fk_name = 'parent_message' # or 'child_message' depending on which you want to include

You need to set which of the 2 to be considered as FK in this case

Upvotes: 4

Related Questions