Commit aced6994 by Oleg Marshev

Use models in views.

parent c38270d5
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import notesapi.v1.models
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='Note',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('user_id', models.CharField(max_length=255)),
('course_id', notesapi.v1.models.CourseKeyField(max_length=255)),
('usage_id', notesapi.v1.models.UsageKeyField(max_length=255)),
('text', models.TextField(default=b'')),
('quote', models.TextField(default=b'')),
('range_start', models.CharField(max_length=2048)),
('range_start_offset', models.IntegerField()),
('range_end', models.CharField(max_length=2048)),
('range_end_offset', models.IntegerField()),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
],
options={
},
bases=(models.Model,),
),
]
...@@ -128,32 +128,27 @@ class Note(models.Model): ...@@ -128,32 +128,27 @@ class Note(models.Model):
updated = models.DateTimeField(auto_now=True) updated = models.DateTimeField(auto_now=True)
def clean(self, json_body): def clean(self, note):
""" """
Clean the note object or raises a ValidationError. Clean the note object or raises a ValidationError.
""" """
if json_body is None: if note is None:
raise ValidationError('Note must have a body.') raise ValidationError('Note must have a body.')
try: if type(note) is not dict:
body = json.loads(json_body) raise ValidationError('Note must be a dictionary.')
except (ValueError, TypeError) as error:
raise ValidationError('Note must have a valid json.')
if not type(body) is dict:
raise ValidationError('Note body must be a dictionary.')
self.text = body.get('text', '') self.text = note.get('text', '')
self.quote = body.get('quote', '') self.quote = note.get('quote', '')
try: try:
self.course_id = CourseLocator.from_string(body['course_id']) self.course_id = CourseLocator.from_string(note['course_id'])
self.usage_id = BlockUsageLocator.from_string(body['usage_id']) self.usage_id = BlockUsageLocator.from_string(note['usage_id'])
self.user_id = body['user'] self.user_id = note['user']
except KeyError as error: except KeyError as error:
raise ValidationError('Note must have a course_id and usage_id and user_id.') raise ValidationError('Note must have a course_id and usage_id and user_id.')
ranges = body.get('ranges') ranges = note.get('ranges')
if ranges is None or len(ranges) != 1: if ranges is None or len(ranges) != 1:
raise ValidationError('Note must contain exactly one range.') raise ValidationError('Note must contain exactly one range.')
......
...@@ -25,7 +25,7 @@ class NoteTest(TestCase): ...@@ -25,7 +25,7 @@ class NoteTest(TestCase):
def test_clean_valid_note(self): def test_clean_valid_note(self):
note = Note() note = Note()
note.clean(json.dumps(self.note)) note.clean(self.note)
self.note.update({ self.note.update({
'id': None, 'id': None,
...@@ -47,19 +47,19 @@ class NoteTest(TestCase): ...@@ -47,19 +47,19 @@ class NoteTest(TestCase):
payload.pop(field) payload.pop(field)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
note.clean(json.dumps(payload)) note.clean(payload)
def test_clean_many_ranges(self): def test_clean_many_ranges(self):
note = Note() note = Note()
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
note.clean(json.dumps({ note.clean({
'text': 'foo', 'text': 'foo',
'quote': 'bar', 'quote': 'bar',
'ranges': [{} for i in range(10)] # Too many ranges. 'ranges': [{} for i in range(10)] # Too many ranges.
})) })
def test_save(self): def test_save(self):
note = Note() note = Note()
note.clean(json.dumps(self.note)) note.clean(self.note)
note.save() note.save()
import logging
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from annotator.annotation import Annotation from annotator.annotation import Annotation
from notesapi.v1.models import Note
CREATE_FILTER_FIELDS = ('updated', 'created', 'consumer', 'id') CREATE_FILTER_FIELDS = ('updated', 'created', 'consumer', 'id')
UPDATE_FILTER_FIELDS = ('updated', 'created', 'user', 'consumer') UPDATE_FILTER_FIELDS = ('updated', 'created', 'user', 'consumer')
log = logging.getLogger(__name__)
class AnnotationSearchView(APIView): class AnnotationSearchView(APIView):
""" """
...@@ -75,6 +81,16 @@ class AnnotationListView(APIView): ...@@ -75,6 +81,16 @@ class AnnotationListView(APIView):
if len(filtered_payload) == 0: if len(filtered_payload) == 0:
return Response(status=status.HTTP_400_BAD_REQUEST) return Response(status=status.HTTP_400_BAD_REQUEST)
note = Note()
try:
note.clean(filtered_payload)
except ValidationError as error:
log.debug(error)
return Response(status=status.HTTP_400_BAD_REQUEST)
note.save()
annotation = Annotation(filtered_payload) annotation = Annotation(filtered_payload)
annotation.save(refresh=True) annotation.save(refresh=True)
...@@ -106,34 +122,58 @@ class AnnotationDetailView(APIView): ...@@ -106,34 +122,58 @@ class AnnotationDetailView(APIView):
""" """
Update an existing annotation. Update an existing annotation.
""" """
annotation_id = self.kwargs.get('annotation_id') note_id = self.kwargs.get('annotation_id')
annotation = Annotation.fetch(annotation_id)
if not annotation: try:
note = Note.objects.get(id=note_id)
except Note.DoesNotExist:
return Response('Annotation not found! No update performed.', status=status.HTTP_404_NOT_FOUND) return Response('Annotation not found! No update performed.', status=status.HTTP_404_NOT_FOUND)
if self.request.DATA is not None: es_note = Annotation.fetch(note_id)
updated = _filter_input(self.request.DATA, UPDATE_FILTER_FIELDS)
updated['id'] = annotation_id # use id from URL, regardless of what arrives in JSON payload.
annotation.update(updated) if not es_note:
return Response('Annotation not found! No update performed.', status=status.HTTP_404_NOT_FOUND)
refresh = self.kwargs.get('refresh') != 'false' if note.user_id != es_note['user_id']:
annotation.save(refresh=refresh) return Response(status=status.HTTP_400_BAD_REQUEST)
return Response(annotation) filtered_payload = _filter_input(self.request.DATA, UPDATE_FILTER_FIELDS)
# use id from URL, regardless of what arrives in JSON payload.
filtered_payload['id'] = note_id
es_note.update(updated)
try:
note.clean(filtered_payload)
except ValidationError as e:
log.debug(e)
return Response(status=status.HTTP_400_BAD_REQUEST)
note.save()
refresh = self.kwargs.get('refresh') != 'false'
es_note.save(refresh=refresh)
return Response(es_note)
def delete(self, *args, **kwargs): # pylint: disable=unused-argument def delete(self, *args, **kwargs): # pylint: disable=unused-argument
""" """
Delete an annotation. Delete an annotation.
""" """
annotation_id = self.kwargs.get('annotation_id') note_id = self.kwargs.get('annotation_id')
annotation = Annotation.fetch(annotation_id)
if not annotation: try:
note = Note.objects.get(id=note_id)
except Note.DoesNotExist:
return Response('Annotation not found! No update performed.', status=status.HTTP_404_NOT_FOUND)
es_note = Annotation.fetch(note_id)
if not es_note:
return Response('Annotation not found! No delete performed.', status=status.HTTP_404_NOT_FOUND) return Response('Annotation not found! No delete performed.', status=status.HTTP_404_NOT_FOUND)
annotation.delete() note.delete()
es_note.delete()
# Annotation deleted successfully. # Annotation deleted successfully.
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
......
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