class RoleSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class ContactRoleSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class P2P_TypeSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class Org2Org_TypeSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class P2Org_TypeSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class PersonSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class OrgSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class ContactSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class P2PSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class Org2OrgSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class P2OrgSerializer(serializers.HyperlinkedModelSerializer):
	class Meta:
class Org2PSerializer(serializers.HyperlinkedModelSerializer):
	class Meta: class Person(models.Model):
	slug = models.SlugField(unique=True, editable=False)
	lastName = models.CharField(max_length=100)
	firstName = models.CharField(max_length=100)
	role = models.ForeignKey('PersonRole', blank=True, null=True, related_name='person_role')
	position = models.CharField(max_length=250, blank=True, null=True)
	department = models.CharField(max_length=250, blank=True, null=True)
	gender = models.CharField(max_length=250, blank=True, null=True, choices=gender_types)
	birthdate = models.CharField(blank=True, null=True, max_length=50)
	race = models.CharField(max_length=250, blank=True, null=True, choices=race_types)
	# Minimum ethnicity category of US fed gov't
	ethnicity = models.CharField(max_length=250, blank=True, null=True, choices=ethnicity_types)
	# Relationships
	p_relations = models.ManyToManyField('self', through='P2P', symmetrical=False, related_name='+', blank=True)
	org_relations = models.ManyToManyField('Org', through='P2Org', related_name='people', blank=True)

	notes = models.TextField(blank=True, null=True)

	last_edited_by = models.CharField(max_length=250, blank=True, null=True)

	tags = TaggableManager()

	def __unicode__(self):
		return self.lastName + ", " + self.firstName

	def save(self, *args, **kwargs):
		unique_slugify(self, self.firstName + "-" + self.lastName)
		super(Person, self).save(*args, **kwargs) class Org(models.Model):
	slug = models.SlugField(unique=True, editable=False)
	orgName = models.CharField(max_length=200)
	openRecordsLaw = models.ForeignKey('OpenRecordsLaw', blank=True, null=True)
	# Relationships
	org_relations = models.ManyToManyField('self', through='Org2Org', symmetrical=False, related_name='+', blank=True)
	p_relations = models.ManyToManyField('Person', through="Org2P", related_name='orgs', blank=True)

	notes = models.TextField(blank=True, null=True)

	last_edited_by = models.CharField(max_length=250, blank=True, null=True)

	tags = TaggableManager()

	def __unicode__(self):
		return self.orgName

	def save(self, *args, **kwargs):
		unique_slugify(self, self.orgName)
		super(Org, self).save(*args, **kwargs) class Contact(models.Model):
	'''
	A contact record for persons or orgs.
	'''
	person = models.ForeignKey('Person', blank=True, null=True, editable=False, related_name='person_contact')
	org = models.ForeignKey('Org', blank=True, null=True, editable=False, related_name='org_contact')

	type = models.CharField(max_length=100, choices=contact_types)
	contact = models.CharField(max_length=250, blank=True, null=True)
	role = models.ForeignKey('OrgContactRole', blank=True, null=True)
	notes = models.TextField(blank=True, null=True)

	def clean(self):
		if not self.person and not self.org:
			raise ValidationError(_('Contact information must be associated with either a person or an organization.'), code='no_ent')
		if self.person and self.org:
			raise ValidationError(_('Contact information should be associated with only one person or organization.'), code='too_many_ents')
		if self.type == 'email':
			validate_email(self.contact)
		elif self.type == 'link':
			url = URLValidator()
			url(self.contact)
		elif self.type == 'phone':
			# Add a validator here?
			pass
		else:
			pass

	def __unicode__(self):
		if self.person:
			return self.person.lastName + ", " + self.person.firstName + ": " + self.type
		else:
			return self.org.orgName + ": " + self.type class PersonRole(models.Model):
	'''
	Define some roles, preferably ones useful for filtering on, e.g. "Media Contact", "FOIA Officer".
	'''
	slug = models.SlugField(unique=True, editable=False)
	role = models.CharField(max_length=250)
	description = models.TextField(blank=True, null=True)

	def __unicode__(self):
		return self.role

	def save(self, *args, **kwargs):
		unique_slugify(self, self.role)
		super(PersonRole, self).save(*args, **kwargs) class OrgContactRole(models.Model):
	'''
	Define roles for org contacts, e.g., FOIA email, etc.
	'''
	slug = models.SlugField(unique=True, editable=False)
	role = models.CharField(max_length=250)
	description = models.TextField(blank=True, null=True)

	def __unicode__(self):
		return self.role

	def save(self, *args, **kwargs):
		unique_slugify(self, self.role)
		super(OrgContactRole, self).save(*args, **kwargs) class P2P(models.Model):
	from_ent = models.ForeignKey(Person, related_name='p_from_p')
	to_ent = models.ForeignKey(Person, related_name='p_to_p')
	relation = models.ForeignKey('P2P_Type', blank=True, null=True, related_name='p2p_relation')
	from_date = models.DateField(blank=True, null=True)
	to_date = models.DateField(blank=True, null=True)
	description = models.TextField(blank=True, null=True)
	objects = GetOrNoneManager()

	def clean(self):
		if P2P.objects.get_or_none(from_ent=self.from_ent, to_ent=self.to_ent):
			raise ValidationError(_('That relationship already exists.'), code='already_exists')
		super(P2P, self).clean()

	def __unicode__(self):
		return self.from_ent.lastName + " ... " + self.to_ent.lastName
	'''
	Override save and delete methods to maintain relationship symmetry.
	'''
	def save(self, *args, **kwargs):
		super(P2P, self).save(*args, **kwargs)
		# Enforce Symmetry
		P2P.objects.get_or_create(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)

	def delete(self):
		relation = P2P.objects.get_or_none(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)
		super(P2P, self).delete()
		if relation:
			relation.delete() class Org2Org(models.Model):
	from_ent = models.ForeignKey(Org, related_name='org_from_org')
	to_ent = models.ForeignKey(Org, related_name='org_to_org')
	relation = models.ForeignKey('Org2Org_Type', blank=True, null=True, related_name='org2org_relation')
	from_date = models.DateField(blank=True, null=True)
	to_date = models.DateField(blank=True, null=True)
	description = models.TextField(blank=True, null=True)
	hierarchy = models.CharField(choices=hierarchy_types, default='none', max_length=10)
	objects = GetOrNoneManager()

	def __unicode__(self):
		return self.from_ent.orgName + " ... " + self.to_ent.orgName

	def clean(self):
		if Org2Org.objects.get_or_none(from_ent=self.from_ent, to_ent=self.to_ent):
			raise ValidationError(_('That relationship already exists.'), code='already_exists')
		super(Org2Org, self).clean()

	def save(self, *args, **kwargs):
		super(Org2Org, self).save(*args, **kwargs)
		'''
		Enforce Symmetry.
		An issue: If you change a feature of a relationship, e.g., hierarchy, you'll end up creating a new relationship, and the stale one will persist.
		'''
		relation, got = Org2Org.objects.get_or_create(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description,
			hierarchy=hierarchy_test(self))

	def delete(self, *args, **kwargs):
		# Enforce Symmetry
		relation = Org2Org.objects.get_or_none(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)
		super(Org2Org, self).delete(*args, **kwargs)
		if relation:
			relation.delete() class P2Org(models.Model):
	from_ent = models.ForeignKey(Person, related_name='org_from_p')
	to_ent = models.ForeignKey(Org, related_name='p_to_org')
	relation = models.ForeignKey('P2Org_Type', blank=True, null=True, related_name='p2org_relation')
	from_date = models.DateField(blank=True, null=True)
	to_date = models.DateField(blank=True, null=True)
	description = models.TextField(blank=True, null=True)
	objects = GetOrNoneManager()

	def __unicode__(self):
		return self.from_ent.lastName + " ... " + self.to_ent.orgName

	def clean(self):
		if P2Org.objects.get_or_none(from_ent=self.from_ent, to_ent=self.to_ent):
			raise ValidationError(_('That relationship already exists.'), code='already_exists')
		super(P2Org, self).clean()

	def save(self, *args, **kwargs):
		super(P2Org, self).save(*args, **kwargs)
		# Enforce Symmetry
		Org2P.objects.get_or_create(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)

	def delete(self, *args, **kwargs):
		# Enforce Symmetry
		relation = Org2P.objects.get_or_none(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)
		super(P2Org, self).delete(*args, **kwargs)
		if relation:
			relation.delete() class Org2P(models.Model):
	from_ent = models.ForeignKey(Org, related_name='p_from_org')
	to_ent = models.ForeignKey(Person, related_name='org_to_p')
	relation = models.ForeignKey('P2Org_Type', blank=True, null=True, related_name='org2p_relation')
	from_date = models.DateField(blank=True, null=True)
	to_date = models.DateField(blank=True, null=True)
	description = models.TextField(blank=True, null=True)
	objects = GetOrNoneManager()

	def __unicode__(self):
		return self.from_ent.orgName + " ... " + self.to_ent.lastName

	def clean(self):
		if Org2P.objects.get_or_none(from_ent=self.from_ent, to_ent=self.to_ent):
			raise ValidationError(_('That relationship already exists.'), code='already_exists')
		super(Org2P, self).clean()

	def save(self, *args, **kwargs):
		super(Org2P, self).save(*args, **kwargs)
		# Enforce Symmetry
		P2Org.objects.get_or_create(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)

	def delete(self, *args, **kwargs):
		# Enforce Symmetry
		relation = P2Org.objects.get_or_none(
			from_ent=self.to_ent,
			to_ent=self.from_ent,
			relation=self.relation,
			from_date=self.from_date,
			to_date=self.to_date,
			description=self.description)
		super(Org2P, self).delete(*args, **kwargs)
		if relation:
			relation.delete() class P2P_Type(models.Model):
	slug = models.SlugField(unique=True, editable=False)
	relationship_type = models.CharField(max_length=250)
	objects = GetOrNoneManager()

	def __unicode__(self):
		return self.relationship_type

	def save(self, *args, **kwargs):
		unique_slugify(self, self.relationship_type)
		super(P2P_Type, self).save(*args, **kwargs) class Org2Org_Type(models.Model):
	slug = models.SlugField(unique=True, editable=False)
	relationship_type = models.CharField(max_length=250)
	objects = GetOrNoneManager()

	def __unicode__(self):
		return self.relationship_type

	def save(self, *args, **kwargs):
		unique_slugify(self, self.relationship_type)
		super(Org2Org_Type, self).save(*args, **kwargs) class P2Org_Type(models.Model):
	slug = models.SlugField(unique=True, editable=False)
	relationship_type = models.CharField(max_length=250)
	objects = GetOrNoneManager()

	def __unicode__(self):
		return self.relationship_type

	def save(self, *args, **kwargs):
		unique_slugify(self, self.relationship_type)
		super(P2Org_Type, self).save(*args, **kwargs)
from rest_framework import viewsets
from rolodex.API import serializers
from rolodex.models import Person, Org, Contact, PersonRole, OrgContactRole, P2P, Org2Org, P2Org, Org2P, P2P_Type, Org2Org_Type, P2Org_Type
from rest_framework.views import APIView
from rest_framework.response import Response
from django.shortcuts import get_object_or_404


class RoleViewSet(viewsets.ModelViewSet):
	queryset = PersonRole.objects.all()
	serializer_class = serializers.RoleSerializer


class ContactRoleViewSet(viewsets.ModelViewSet):
	queryset = OrgContactRole.objects.all()
	serializer_class = serializers.ContactRoleSerializer


class P2P_TypeViewSet(viewsets.ModelViewSet):
	queryset = P2P_Type.objects.all()
	serializer_class = serializers.P2P_TypeSerializer


class Org2Org_TypeViewSet(viewsets.ModelViewSet):
	queryset = Org2Org_Type.objects.all()
	serializer_class = serializers.Org2Org_TypeSerializer


class P2Org_TypeViewSet(viewsets.ModelViewSet):
	queryset = P2Org_Type.objects.all()
	serializer_class = serializers.P2Org_TypeSerializer


class PersonViewSet(viewsets.ModelViewSet):

	queryset = Person.objects.all().order_by('id')