Package: django-connections
connectionsis a small app for Django that allows you to model any kind of
relationship between instances ofanymodel. It’s primary use is for
building a social graph that you can query and manage easily.Requirementsconnectionsrequires Python 2.6/3.2 or newer and Django 1.5 or newer.How to installUsing pip:$ pip install django-connectionsManually:$ git clone https://github.com/dfunckt/django-connections.git
$ cd django-connections
$ python setup.py installConfigurationAddconnectionsto your settings:INSTALLED_APPS = (
    # ...
    'connections',
)Then, runmigrate:$ python manage.py migrateNote: If you’re running Django 1.6 or lower, you should runmanage.py syncdbinstead.UsingconnectionsWithconnectionsyou essentially builddirected graphs, where eachnodeis a model instance and eachedgeis aConnectioninstance. Which
two models a connection can connect, is determined by aRelationshipinstance that you predefine.Defining relationshipsAssume you’reLitHub, a social coding site in its infancy, and you need to
let your users star repositories they find interesting. Withconnections,
you would first define a relationship:>>> from django.contrib.auth.models import User
>>> from connections import define_relationship
>>> from lithub.models import Repo
>>> repo_stars = define_relationship('star_repo', from_model=User, to_model=Repo)define_relationshipcreates and registers a newRelationshipinstance
between the given models, with the name'star_repo'. Names of
relationships must be unique across your project. You may alternatively
specify the models of the relationship as strings, e.g.'auth.User'or'lithub.Repo'.Any time you need to reference a relationship, you can either import the
module variable (as defined above), or useconnections.get_relationship(name).Managing connectionsLet’s say thatmilofound a nice Python project on LitHub that he’d like
to star, for future reference. Inconnectionsthis can be modelled by
creating a connection betweenmiloand the repository instance:>>> milo = User.objects.get(pk=104)
>>> foopy = Repo.objects.get(pk=47)
>>> star_repo.create_connection(milo, foopy)
'star_repo (auth.User:104 -> lithub.Repo:47)'Connections are unidirectional, meaning that iffoois connected withbar, the reverse – thatbaris connected tofoo– isnotimplied.
If you’d like to model a symmetrical relationship, that is, one that only
makes sense if both sides have agreed in the relationship (e.g.friendshipor evenmarriage), you’d have to create two opposite connections, one for
each side of the relationship.Let’s see what repositoriesmilohas starred:>>> repo_stars.connected_objects(milo)
[<Repo: foopy>]We can also query for the reverse, that is, what users have starredfoopy:>>> repo_stars.connected_to_objects(foopy)
[<User: milo>]There are several other methods you may use to query or manage connections,
that you may read about inAPI Reference.Best practicesThe preferred idiom is to define relationships inapp/relationships.pyfiles, keeping a module-global reference to each relationship instance,
through which you manage connections between your model instances.If you’re using Django 1.7 or later you may have anyrelationships.pymodules automatically imported at start-up:INSTALLED_APPS = (
    # ...
    'connections.apps.AutodiscoverConnectionsConfig',
)API ReferenceClassRelationshipRepresents a predefined type of connection between two nodes in a (directed)
graph. You may imagine relationships as thekindof an edge in the graph.>>> from connections.models import Relationship
>>> rel = Relationship('rel_name', from_content_type, to_content_type)Instance propertiesconnectionsReturns aConnectionquery set matching all connections of this
relationship.Instance methodscreate_connection(from_obj, to_obj)Creates and returns a newConnectioninstance between the given
objects. If a connection already exists, the existing connection will be
returned instead of creating a new one.get_connection(from_obj, to_obj)Returns aConnectioninstance for the given objects orNoneif
there’s no connection.connection_exists(from_obj, to_obj)ReturnsTrueif a connection between the given objects exists,
elseFalse.connections_from_object(from_obj)Returns aConnectionquery set matching all connections with
the given object as a source.connections_to_object(to_obj)Returns aConnectionquery set matching all connections with
the given object as a destination.connected_objects(from_obj)Returns a query set matching all connected objects with the given
object as a source.connected_object_ids(from_obj)Returns an iterable of the IDs of all objects connected with the given
object as a source (i.e. theConnection.to_pkvalues).connected_to_objects(to_obj)Returns a query set matching all connected objects with the given
object as a destination.connected_to_object_ids(to_obj)Returns an iterable of the IDs of all objects connected with the given
object as a destination (i.e. theConnection.from_pkvalues).distance_between(from_obj, to_obj, limit=2)Calculates and returns an integer for the distance between two objects.
A distance of0meansfrom_objandto_objare the same
objects,1meansfrom_objhas a direct connection toto_obj,2means that one or more offrom_obj’s connected objects are
directly connected toto_obj, and so on.limitlimits the depth of
connections traversal. ReturnsNoneif the two objects are not
connected withinlimitdistance.ClassConnectionRepresents a connection between two nodes in the graph. Connections must
be treated as unidirectional, i.e. creating a connection from one node to
another should not imply the reverse.Model attributesrelationship_nameThe name of the relationship. To access the relationship instance, use theConnection.relationshipproperty.from_pkThe primary key of the instance acting as source.to_pkThe primary key of the instance acting as destination.dateAdatetimeinstance of the time the connection was created.Instance propertiesrelationshipReturns theRelationshipinstance the connection is about.from_objectThe source instance.to_objectThe destination instance.