Commit e1e473bb by chrisndodge

Merge pull request #13 from edx-solutions/cdodge/add-group-profile

Cdodge/add group profile
parents 75942770 c8e1dbbc
""" API implementation for group-oriented interactions. """ """ API implementation for group-oriented interactions. """
import uuid import uuid
import json
from collections import OrderedDict
from django.contrib.auth.models import Group, User from django.contrib.auth.models import Group, User
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
...@@ -10,7 +12,7 @@ from rest_framework.decorators import api_view, permission_classes ...@@ -10,7 +12,7 @@ from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response from rest_framework.response import Response
from api_manager.permissions import ApiKeyHeaderPermission from api_manager.permissions import ApiKeyHeaderPermission
from api_manager.models import GroupRelationship, CourseGroupRelationship from api_manager.models import GroupRelationship, CourseGroupRelationship, GroupProfile
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import Location, InvalidLocationError from xmodule.modulestore import Location, InvalidLocationError
...@@ -32,46 +34,73 @@ def _generate_base_uri(request): ...@@ -32,46 +34,73 @@ def _generate_base_uri(request):
return resource_uri return resource_uri
@api_view(['POST']) @api_view(['GET', 'POST'])
@permission_classes((ApiKeyHeaderPermission,)) @permission_classes((ApiKeyHeaderPermission,))
def group_list(request): def group_list(request):
""" """
GET retrieves a list of groups in the system filtered by type
POST creates a new group in the system POST creates a new group in the system
""" """
response_data = {} if request.method == 'GET':
base_uri = _generate_base_uri(request) if not 'type' in request.GET:
# Group name must be unique, but we need to support dupes return Response({}, status=status.HTTP_400_BAD_REQUEST)
group = Group.objects.create(name=str(uuid.uuid4()))
original_group_name = request.DATA['name'] response_data = []
group.name = '{:04d}: {}'.format(group.id, original_group_name) profiles = GroupProfile.objects.filter(group_type=request.GET['type'])
group.record_active = True for profile in profiles:
group.record_date_created = timezone.now() item_data = OrderedDict()
group.record_date_modified = timezone.now() item_data['group_id'] = profile.group_id
group.save() item_data['group_type'] = profile.group_type
# Relationship model also allows us to use duplicate names item_data['data'] = json.loads(profile.data)
GroupRelationship.objects.create(name=original_group_name, group_id=group.id, parent_group=None) response_data.append(item_data)
response_data = {'id': group.id, 'name': original_group_name}
base_uri = _generate_base_uri(request) return Response(response_data)
response_data['uri'] = '{}/{}'.format(base_uri, group.id) elif request.method == 'POST':
response_status = status.HTTP_201_CREATED response_data = {}
return Response(response_data, status=response_status) base_uri = _generate_base_uri(request)
# Group name must be unique, but we need to support dupes
group = Group.objects.create(name=str(uuid.uuid4()))
original_group_name = request.DATA['name']
group.name = '{:04d}: {}'.format(group.id, original_group_name)
group.record_active = True
group.record_date_created = timezone.now()
group.record_date_modified = timezone.now()
group.save()
# Relationship model also allows us to use duplicate names
GroupRelationship.objects.create(name=original_group_name, group_id=group.id, parent_group=None)
# allow for optional meta information about groups, this will end up in the GroupProfile table
group_type = request.DATA.get('group_type')
data = request.DATA.get('data')
if group_type or data:
profile, _ = GroupProfile.objects.get_or_create(group_id=group.id, group_type=group_type, data=data)
response_data = {'id': group.id, 'name': original_group_name}
base_uri = _generate_base_uri(request)
response_data['uri'] = '{}/{}'.format(base_uri, group.id)
response_status = status.HTTP_201_CREATED
return Response(response_data, status=response_status)
@api_view(['GET']) @api_view(['GET', 'POST'])
@permission_classes((ApiKeyHeaderPermission,)) @permission_classes((ApiKeyHeaderPermission,))
def group_detail(request, group_id): def group_detail(request, group_id):
""" """
GET retrieves an existing group from the system GET retrieves an existing group from the system
""" """
response_data = {} response_data = {}
base_uri = _generate_base_uri(request) base_uri = _generate_base_uri(request)
try: try:
existing_group = Group.objects.get(id=group_id) existing_group = Group.objects.get(id=group_id)
existing_group_relationship = GroupRelationship.objects.get(group_id=group_id) existing_group_relationship = GroupRelationship.objects.get(group_id=group_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
existing_group = None return Response({}, status.HTTP_404_NOT_FOUND)
existing_group_relationship = None
if existing_group and existing_group_relationship: if request.method == 'GET':
response_data['name'] = existing_group_relationship.name response_data['name'] = existing_group_relationship.name
response_data['id'] = existing_group.id response_data['id'] = existing_group.id
response_data['uri'] = base_uri response_data['uri'] = base_uri
...@@ -80,10 +109,36 @@ def group_detail(request, group_id): ...@@ -80,10 +109,36 @@ def group_detail(request, group_id):
response_data['resources'].append({'uri': resource_uri}) response_data['resources'].append({'uri': resource_uri})
resource_uri = '{}/groups'.format(base_uri) resource_uri = '{}/groups'.format(base_uri)
response_data['resources'].append({'uri': resource_uri}) response_data['resources'].append({'uri': resource_uri})
# see if there is an (optional) GroupProfile
try:
existing_group_profile = GroupProfile.objects.get(group_id=group_id)
if existing_group_profile.group_type:
response_data['group_type'] = existing_group_profile.group_type
data = existing_group_profile.data
if data:
response_data['data'] = json.loads(data)
except ObjectDoesNotExist:
pass
response_status = status.HTTP_200_OK response_status = status.HTTP_200_OK
else:
response_status = status.HTTP_404_NOT_FOUND return Response(response_data, status=response_status)
return Response(response_data, status=response_status) elif request.method == 'POST':
# update GroupProfile data
group_type = request.DATA.get('group_type')
data = request.DATA.get('data')
if not group_type and not data:
return Response({}, status.HTTP_400_BAD_REQUEST)
profile, _ = GroupProfile.objects.get_or_create(group_id=group_id)
profile.group_type = group_type
profile.data = data
profile.save()
return Response({})
@api_view(['POST']) @api_view(['POST'])
......
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'CourseGroupRelationship'
db.create_table('api_manager_coursegrouprelationship', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('course_id', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Group'])),
))
db.send_create_signal('api_manager', ['CourseGroupRelationship'])
# Adding model 'GroupProfile'
db.create_table('auth_groupprofile', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Group'])),
('group_type', self.gf('django.db.models.fields.CharField')(max_length=32, null=True, db_index=True)),
('data', self.gf('django.db.models.fields.TextField')(blank=True)),
))
db.send_create_signal('api_manager', ['GroupProfile'])
def backwards(self, orm):
# Deleting model 'CourseGroupRelationship'
db.delete_table('api_manager_coursegrouprelationship')
# Deleting model 'GroupProfile'
db.delete_table('auth_groupprofile')
models = {
'api_manager.coursegrouprelationship': {
'Meta': {'object_name': 'CourseGroupRelationship'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'api_manager.groupprofile': {
'Meta': {'object_name': 'GroupProfile', 'db_table': "'auth_groupprofile'"},
'data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}),
'group_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'api_manager.grouprelationship': {
'Meta': {'object_name': 'GroupRelationship'},
'group': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'parent_group': ('django.db.models.fields.related.ForeignKey', [], {'default': '0', 'related_name': "'child_groups'", 'null': 'True', 'blank': 'True', 'to': "orm['api_manager.GroupRelationship']"}),
'record_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'record_date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 4, 21, 0, 0)'}),
'record_date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'api_manager.linkedgrouprelationship': {
'Meta': {'object_name': 'LinkedGroupRelationship'},
'from_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'from_group_relationships'", 'to': "orm['api_manager.GroupRelationship']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'record_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'record_date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 4, 21, 0, 0)'}),
'record_date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'to_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'to_group_relationships'", 'to': "orm['api_manager.GroupRelationship']"})
},
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['api_manager']
\ No newline at end of file
...@@ -92,3 +92,19 @@ class CourseGroupRelationship(models.Model): ...@@ -92,3 +92,19 @@ class CourseGroupRelationship(models.Model):
""" """
course_id = models.CharField(max_length=255, db_index=True) course_id = models.CharField(max_length=255, db_index=True)
group = models.ForeignKey(Group, db_index=True) group = models.ForeignKey(Group, db_index=True)
class GroupProfile(models.Model):
"""
This table will provide additional tables regarding groups. This has a foreign key to
the auth_groups table
"""
class Meta:
db_table = "auth_groupprofile"
group = models.ForeignKey(Group, db_index=True)
group_type = models.CharField(null=True, max_length=32, db_index=True)
data = models.TextField(blank=True) # JSON dictionary for generic key/value pairs
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment