django-teledex

Simple storage of addresses, phone numbers and emails in Django Models.

django-teledex supports Python 2.7, 3.3, 3.4 and pypy for Django 1.7 and 1.8.

Contents

Installation

You can install django-teledex either via the Python Package Index (PyPI) or from github.

To install using pip;

$ pip install django-teledex

From github;

$ pip install git+https://github.com/alexhayes/django-teledex.git

Then place django_teledex in your INSTALLED_APPS;

INSTALLED_APPS = (
    ...
    'django_teledex',
    ...
)

Usage

There are three models Address, PhoneNumber and Email which all present essentially the same API.

For the examples below let’s assume you have the following model;

# models.py

from django.db import models
from django_teledex.fields import AddressRelation, PhoneNumberRelation, EmailRelation


class Company(models.Model):
    title = models.CharField(max_length=100)
    addresses = AddressRelation('companies')
    phonenumbers = PhoneNumberRelation('companies')
    emails = EmailRelation('companies')

Address

If you want to add an address you can then do the following;

from django_teledex.models import Address
from django_teledex.choices import AddressKind


company = Company.objects.create(title='Evelyn Hotel')

address = Address.objects.create(
    organisation=company.title,
    kind=AddressKind.physical,
    owner=company,
    address_line='351 Brunswick St',
    locality='Fitzroy',
    region='VIC',
    postcode='3065',
    country='AU',
)

company.addresses.all() # returns all addresses for company
company.addresses.active() # all active addresses

# Make an address inactive
address.deactivate()

company.addresses.inactive() # all inactive addresses
company.addresses.kind(AddressKind.physical) # get addresses by kind
company.addresses.filter(postcode=3065) # filter works as you'd expect...

# Make an address active
address.activate()

A complete list of QuerySet methods available on Address.objects is available in django_teledex.models.AddressQuerySet.

PhoneNumber

The PhoneNumber model behaves in pretty much the same way, for example;

from django_teledex.models import PhoneNumber
from django_teledex.choices import PhoneNumberKind

company = Company.objects.create(title='Evelyn Hotel')

phonenumber = PhoneNumber.objects.create(
    kind=PhoneNumberKind.mobile,
    owner=company,
    number='+61 3 9419 5500'
)

company.phonenumbers.all() # returns all phone numbers for company
company.phonenumbers.active() # all active phone numbers

# Make an phone number inactive
phonenumber.deactivate()

company.phonenumbers.inactive() # all inactive addresses
company.phonenumbers.kind(PhoneNumberKind.mobile) # by kind
company.phonenumbers.filter(kind=PhoneNumberKind.mobile) # filter works as you'd expect...

# Make an phone number active
phonenumber.activate()

A complete list of QuerySet methods available on PhoneNumber.objects is available in django_teledex.models.PhoneNumberQuerySet.

Validation

PhoneNumber is a PhoneNumberField which comes from django-phonenumber-field which;

is a library which interfaces with python-phonenumbers to validate, pretty print and convert phone numbers. python-phonenumbers is a port of Google’s libphonenumber library, which powers Android’s phone number handling.

You’ll probably want to look into the above to get familiar with how they are useful to your project.

Email

The Email model also behaves in pretty much the same way, for example;

from django_teledex.models import Email
from django_teledex.choices import EmailKind

company = Company.objects.create(title='Evelyn Hotel')

email = Email.objects.create(
    kind=EmailKind.work,
    owner=company,
    email='guys@example.com'
)

company.emails.all() # returns all phone numbers for company
company.emails.active() # all active phone numbers

# Make an phone number inactive
email.deactivate()

company.emails.inactive() # all inactive addresses
company.emails.kind(EmailKind.work) # by kind
company.emails.filter(email__icontains='guys@') # filter works as you'd expect...

# Make an phone number active
email.activate()

A complete list of QuerySet methods available on Email.objects is available in django_teledex.models.EmailQuerySet.

Reverse Relations

You can also traverse back from an Address, PhoneNumber or Email to the owner, in this case the Company - all thanks to Django’s reverse generic relations.

django_teledex.fields.AddressRelation, django_teledex.fields.PhoneNumberRelation and django_teledex.fields.EmailRelation are simply helper classes that inherit from GenericRelation that set some defaults.

The first, and only required, argument to each of the *Relation classes is the related_query_name used by the GenericRelation which django_teledex.fields.AddressRelation, django_teledex.fields.PhoneNumberRelation and django_teledex.fields.EmailRelation inherit from. In the Company model above it’s set to companies.

Thus;

# Reverse relations
Address.objects.filter(companies__title='Evelyn Hotel')

Developer Documentation

Contributions

Contributions are more than welcomed!

To get setup do the following;

mkvirtualenv --python=/usr/bin/python3 django-teledex
git clone https://github.com/alexhayes/django-teledex.git
cd django-teledex
pip install -r requirements/dev.txt

Note that you don’t have to use Python 3 and indeed tox tests for many versions of Python, but you may as well develop on it, what reason is there not to for such a small application?!

Running Tests

Once you’ve checked out you should be able to run the tests.

detox

or, alternatively;

./manage.py test

Migrations

If you need to make modelling changes please run makemigrations so that the migration is included in your pull request.

./manage.py makemigrations

Creating translations

Translations are welcomed! Please fork and then from the root

cd django_teledex
./../manage.py makemessages -l [LOCALE-NAME]

Then, edit the translations in django_teledex/locale, then;

./../manage.py compilemessages

Creating Documentation

cd docs
make clean html

Internal Module Reference

Release:0.2.0
Date:September 16, 2015

django_teledex.choices

Define choices that can be used within django-teledex.

django_teledex.fields

Defines helper classes used for defining GenericRelation on models.

See Usage.

class django_teledex.fields.AddressRelation(related_query_name, **kwargs)[source]

Bases: django_teledex.fields.BaseRelation

Helper used to map your own model to an django_teledex.models.Address

This class can be used to setup the GenericRelation between your own model and an django_teledex.models.Address.

class django_teledex.fields.BaseRelation(to, related_query_name, **kwargs)[source]

Bases: django.contrib.contenttypes.fields.GenericRelation

Helper class useful for automatically setting content_type_field and object_id_field.

class django_teledex.fields.EmailRelation(related_query_name, **kwargs)[source]

Bases: django_teledex.fields.BaseRelation

Helper used to map your own model to an django_teledex.models.Email

This class can be used to setup the GenericRelation between your own model and an django_teledex.models.Email.

class django_teledex.fields.PhoneNumberRelation(related_query_name, **kwargs)[source]

Bases: django_teledex.fields.BaseRelation

Helper used to map your own model to an django_teledex.models.PhoneNumber

This class can be used to setup the GenericRelation between your own model and an django_teledex.models.PhoneNumber.

teledex.models

Django models for django-teledex.

class django_teledex.models.Address(*args, **kwargs)[source]

Bases: django.db.models.base.Model

Defines an Address.

Sigh... if only we had a port of libaddressinput in Python... :(

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Address.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Address.country = <django_countries.fields.CountryField>
Address.get_country_display(*moreargs, **morekwargs)
Address.get_kind_display(*moreargs, **morekwargs)
Address.get_status_display(*moreargs, **morekwargs)
Address.joined()[source]

Join the address into a single line string separated by commas.

Return type:str
Address.objects = <django.db.models.manager.ManagerFromAddressQuerySet object>
Address.owner

Provides a generic relation to any object through content-type/object-id fields.

Address.owner_type
class django_teledex.models.AddressQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: django.db.models.query.QuerySet

Address QuerySet.

active()[source]

Filter for active Addresses

Return type:AddressQuerySet
inactive()[source]

Filter for inactive Addresses

Return type:AddressQuerySet
kind(kind)[source]

Filter addresses by a particular kind.

Accepts any of the

Return type:AddressQuerySet
physical()[source]

Filter for physical addresses.

Return type:AddressQuerySet
postal()[source]

Filter for postal addresses.

Return type:AddressQuerySet
class django_teledex.models.Email(*args, **kwargs)[source]

Bases: django.db.models.base.Model

Defines a Phone Number.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception Email.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

Email.get_kind_display(*moreargs, **morekwargs)
Email.get_status_display(*moreargs, **morekwargs)
Email.objects = <django.db.models.manager.ManagerFromEmailQuerySet object>
Email.owner

Provides a generic relation to any object through content-type/object-id fields.

Email.owner_type
class django_teledex.models.EmailQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: django.db.models.query.QuerySet

Email QuerySet.

active()[source]

Filter for active Phone Numbers

inactive()[source]

Filter for inactive Phone Numbers

kind(kind)[source]
class django_teledex.models.PhoneNumber(*args, **kwargs)[source]

Bases: django.db.models.base.Model

Defines a Phone Number.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception PhoneNumber.MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

PhoneNumber.get_kind_display(*moreargs, **morekwargs)
PhoneNumber.get_status_display(*moreargs, **morekwargs)
PhoneNumber.number = <phonenumber_field.modelfields.PhoneNumberField>
PhoneNumber.objects = <django.db.models.manager.ManagerFromPhoneNumberQuerySet object>
PhoneNumber.owner

Provides a generic relation to any object through content-type/object-id fields.

PhoneNumber.owner_type
class django_teledex.models.PhoneNumberQuerySet(model=None, query=None, using=None, hints=None)[source]

Bases: django.db.models.query.QuerySet

PhoneNumber QuerySet.

active()[source]

Filter for active Phone Numbers

inactive()[source]

Filter for inactive Phone Numbers

kind(kind)[source]

License

This software is licensed under the MIT License. See the LICENSE file in the top distribution directory for the full license text.

Author

Alex Hayes <alex@alution.com>