Reversing a unique Generic Foreign Key with Django

🤯 2020 Update: This is an old post. It might not still be the best way to do things. Buyer beware.

Django’s generic foreign keys makes it very easy to create a unique generic object that can be attached to any model instance. The following is a contact card that we can attach to people or users:
class ContactDetails(models.Model):
    phone_number = models.CharField(...)
    address = models.CharField(...)


    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    class Meta:
        unique_together = ('content_type', 'object_id',)

class User(models.Model):
    contacts = generic.GenericRelation(ContactDetails, object_id_field="object_pk")
user = User.objects.get(pk=1)
contact_card = user.contacts.all()[0]

This works, but it’s a little bulky as we have to navigate the RelatedManager every time we want to return the object on the other end of our one-to-one relationship. A simple solution is to create a mixin that will make this transparent:
class ContactMixin(object):

    def contact_card(self):
        ctype = ContentType.objects.get_for_model(self.__class__)
            contact = Contact.objects.get(content_type__pk =,
        except Contact.DoesNotExist:
            return None
        return contact

    class User(models.Model, ContactMixin):

Now we don’t have to meddle with the related manager; we can instead access our instance object directly:

user = User.objects.get(pk=1)
print user.contact_card.phone_number