4

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.

user1330974
  • 2,500
  • 5
  • 32
  • 60
  • Possible duplicate of [Django Admin inline for recursive ManyToMany](https://stackoverflow.com/questions/8177609/django-admin-inline-for-recursive-manytomany) – bjunix Nov 02 '19 at 13:54

2 Answers2

3

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

karthikr
  • 97,368
  • 26
  • 197
  • 188
  • Thank you @karthikr! That works and show at least the child message of any message. I have a related question that is to prevent all possible children messages from being shown in the drop down list in admin console. Since I hope to populate quite a lot of messages in the database, I don't want Django to be showing all possible choices as drop-down in the console. This problem has been discussed here at [link](http://stackoverflow.com/questions/9342624/representing-manytomany-relation-in-the-admin-panel) but when I added `raw_id_fields=('parent_message',)` in `RelationshipInline`, it doesn't.. – user1330974 Jun 21 '13 at 18:28
  • (cont.) work. I plan to do a new post about this, but if you happen to know this, please let me know how to prevent Django admin to show all possible selections as drop-down in Many-to-Many, Inline displays. Thank you. – user1330974 Jun 21 '13 at 18:29
  • You are probably looking for this: http://stackoverflow.com/questions/6581520/filtering-dropdown-values-in-django-admin You basically are looking to filter the queryset based on criteria, which is covered in that post – karthikr Jun 21 '13 at 18:30
  • Sorry, got your question wrong. Have answered. That should most likely work – karthikr Jun 21 '13 at 18:55
0

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.

Victor Castillo Torres
  • 10,581
  • 7
  • 40
  • 50
  • Thanks for the answer. @karthikr's solution works (to show parent message/relationship). – user1330974 Jun 21 '13 at 18:23
  • This isn't true - at least anymore, you can have a through for Many2many on self, but you have to specify symmetric = False (I was reading docs from your link) – amchugh89 Dec 05 '16 at 00:47