views:

210

answers:

1

I want to build an undirected graph in Django. I have built an edge model with two foreign keys (first,second) to the node class, but there is a conflict with the related_name. I can use first_set and second_set, but since the graph is undirected, it doesn't matter if it is being liked to or from. What is the recommended way to deal with this scenario?

Edit: Here are roughly the models I'm working with:

class Node(models.Model):
    #some irrelevant stuff

class Edge(models.Model):
    #some other stuff
    first = models.ForeignKey('Node',related_name=None)
    second = models.ForeignKey('Node',related_name=None)

What I would like to have is some_node.connected_nodes_set be something to the effect of a RelatedManager, similar to what would have been setup for either the first_set or second_set had I used related_names, except that it would have all of the nodes that can be reached with a single edge, instead of just those which can be reached in one direction.

+1  A: 

I had to do something similar with my current project. My solution was to have a ManyToManyField in my equivalent to your Node model. Something like this:

class Node(models.Model):
    adjacent = models.ManyToManyField("self", null=True, blank=True)

Note that the "self" above is necessary to allow the ManyToManyField to point back to itself.

Using this code, all nodes adjacent to a given node N can be found using N.adjacent.all().

Jeff Bradberry
This looks promising, but the problem is that I need some extra data in the edge model. At first thought, it would seem that I could use a ManyToManyField("self",through="Edge",symmetrical=True), but the documentation specifically says that you must use symmetrical=False if you are using a through model.
Bryan Ward
You'll have to make sure that the inverse relationship is created every time you make an `Edge`, then. Off of the top of my head, that should be possible to do automatically by overriding `Edge`'s `save` method.
Jeff Bradberry