--- a/src/p4l/api/serializers.py Sat Sep 07 14:41:20 2013 +0200
+++ b/src/p4l/api/serializers.py Mon Sep 09 01:48:26 2013 +0200
@@ -5,11 +5,12 @@
@author: ymh
'''
from django.core.exceptions import ValidationError
-from p4l.models import (Record, Title, Issn, Isbn, DocumentCode, Abstract,
- AddedTitle, TitleMainDocument, Imprint, Collation, VolumeIssue, Periodical,
- Meeting, SubjectMeeting, Serie, Url)
+from p4l.models import Record
from rest_framework import serializers
import logging
+from rest_framework.serializers import NestedValidationError
+import copy
+from django.db.models.fields.related import ForeignKey
logger = logging.getLogger(__name__)
@@ -32,84 +33,87 @@
raise ValidationError(msg)
-class BaseTitleSerializer(serializers.ModelSerializer):
- class Meta:
- fields = ('title', 'lang')
+class P4lModelSerializer(serializers.ModelSerializer):
+
-class TitleSerializer(BaseTitleSerializer):
- class Meta(BaseTitleSerializer.Meta):
- model = Title
+ def get_nested_field(self, model_field, related_model, to_many):
+ field_exclude = ()
+ if model_field is None:
+ fk = [f.name for f in related_model._meta.fields if (isinstance(f, ForeignKey) and f.rel.to == Record)][0]
+ field_exclude = ('id', fk)
+ class NestedModelSerializer(P4lModelSerializer):
+ class Meta:
+ model = related_model
+ depth = self.opts.depth - 1
+ exclude = field_exclude
-class AddedTitleSerializer(BaseTitleSerializer):
- class Meta(BaseTitleSerializer.Meta):
- model = AddedTitle
-
-class TitleMainDocumentSerializer(BaseTitleSerializer):
- class Meta(BaseTitleSerializer.Meta):
- model = TitleMainDocument
+ return NestedModelSerializer(many=to_many)
-class IssnSerializer(serializers.ModelSerializer):
- class Meta:
- model = Issn
- fields = ('issn', 'lang')
-
-class IsbnSerializer(serializers.ModelSerializer):
- class Meta:
- model = Isbn
- fields = ('isbn', 'lang')
-
-class DocumentCodeSerializer(serializers.ModelSerializer):
- class Meta:
- model = DocumentCode
- fields = ('documentCode', 'lang')
+
+ def field_from_native(self, data, files, field_name, into):
+ """
+ Override default so that the serializer can be used as a writable
+ nested field across relationships.
+ """
+ if self.read_only:
+ return
-class AbstractSerializer(serializers.ModelSerializer):
- class Meta:
- model = Abstract
- fields = ('abstract', 'lang')
+ try:
+ value = data[field_name]
+ except KeyError:
+ if self.default is not None and not self.partial:
+ # Note: partial updates shouldn't set defaults
+ value = copy.deepcopy(self.default)
+ else:
+ if self.required:
+ raise ValidationError(self.error_messages['required'])
+ return
-class ImprintSerializer(serializers.ModelSerializer):
- class Meta:
- model = Imprint
- fields = ('imprintCity', 'publisher', 'imprintDate', 'lang')
-
-class CollationSerializer(serializers.ModelSerializer):
- class Meta:
- model = Collation
- fields = ('collation', 'lang')
-
-class VolumeIssueSerializer(serializers.ModelSerializer):
- class Meta:
- model = VolumeIssue
- fields = ('volume', 'number', 'lang')
-
-class PeriodicalSerializer(serializers.ModelSerializer):
- class Meta:
- model = Periodical
- fields = ('label', 'lang')
+ # Set the serializer object if it exists
+ obj = getattr(self.parent.object, field_name) if self.parent.object else None
-class MeetingSerializer(serializers.ModelSerializer):
- class Meta:
- model = Meeting
- fields = ('label', 'meetingNumber', 'meetingPlace', 'meetingDate', 'meetingYear', 'lang')
-
-class SubjectMeetingSerializer(serializers.ModelSerializer):
- class Meta:
- model = SubjectMeeting
- fields = ('label', 'meetingNumber', 'meetingPlace', 'meetingDate', 'meetingYear')
+ if self.source == '*':
+ if value:
+ into.update(value)
+ else:
+ if value in (None, ''):
+ into[(self.source or field_name)] = None
+ elif self.many and hasattr(value, '__iter__'):
+ obj.all().delete()
+ nested_items = []
+ for val in value:
+ kwargs = {
+ 'instance': None,
+ 'data': val,
+ 'context': self.context,
+ 'partial': self.partial,
+ 'many': False
+ }
+ serializer = self.__class__(**kwargs)
+ nested_items.append(serializer.from_native(val, files))
+ into[self.source or field_name] = nested_items
+ else:
+ kwargs = {
+ 'instance': obj,
+ 'data': value,
+ 'context': self.context,
+ 'partial': self.partial,
+ 'many': self.many
+ }
+ serializer = self.__class__(**kwargs)
-class SerieSerializer(serializers.ModelSerializer):
- class Meta:
- model = Serie
- fields = ('title', 'volume', 'lang')
-
-class UrlSerializer(serializers.ModelSerializer):
- class Meta:
- model = Url
- fields = ('address', 'display', 'accessLevel')
+ if serializer.is_valid():
+ into[self.source or field_name] = serializer.object
+ else:
+ # Propagate errors up to our parent
+ raise NestedValidationError(serializer.errors)
-class RecordSerializer(serializers.ModelSerializer):
+
+
+
+#class RecordSerializer(serializers.ModelSerializer):
+class RecordSerializer(P4lModelSerializer):
'''
Serializer for record
'''
@@ -121,23 +125,6 @@
projectNames = ThesaurusSerializer(many=True, slug_field='uri')
subjectCorporateBodies = ThesaurusSerializer(many=True, slug_field='uri')
corporateAuthors = ThesaurusSerializer(many=True, slug_field='uri')
-# titles = TitleSerializer(many=True, read_only=False)
-# addedTitles = AddedTitleSerializer(many=True, read_only=False)
-# issns = IssnSerializer(many=True, read_only=False)
-# isbns = IsbnSerializer(many=True, read_only=False)
-# documentCodes = DocumentCodeSerializer(many=True, read_only=False)
-# abstracts = AbstractSerializer(many=True, read_only=False)
-# titlesMainDocument = TitleMainDocumentSerializer(many=True, read_only=False)
-# imprints = ImprintSerializer(many=True, read_only=False)
-# collations = CollationSerializer(many=True, read_only=False)
-# volumeIssues = VolumeIssueSerializer(many=True, read_only=False)
-# periodicals = PeriodicalSerializer(many=True, read_only=False)
-# meetings = MeetingSerializer(many=True, read_only=False)
-# subjectMeetings = SubjectMeetingSerializer(many=True, read_only=False)
-# series = SerieSerializer(many=True, read_only=False)
-# authors = serializers.SlugRelatedField(many=True, read_only=False, slug_field="name")
-# subjectPersons = serializers.SlugRelatedField(many=True, read_only=False, slug_field="name")
-# urls = UrlSerializer(many=True, read_only=False)
class Meta:
model = Record
@@ -146,16 +133,10 @@
fields = ("identifier", "uri", "subjects", "notes", "otherLanguages",
"language", "editionStatement", "recordType", "isDocumentPart",
"isMultilingual", "themes", "countries", "projectNames",
- "subjectCorporateBodies", "corporateAuthors")
-# fields = (
-# "editionStatement", "recordType","isDocumentPart",
-# "isMultilingual","subjects", "themes", "countries",
-# "projectNames", "subjectCorporateBodies", "corporateAuthors",
-# "titles", "issns", "isbns", "documentCodes", "abstracts",
-# "addedTitles", "titlesMainDocument", "imprints",
-# "collations", "volumeIssues", "periodicals", "meetings",
-# "subjectMeetings", "series", "authors", "subjectPersons",
-# "urls")
-
+ "subjectCorporateBodies", "corporateAuthors", "imprints",
+ "titles", "addedTitles", "issns", "isbns", "documentCodes",
+ "abstracts", "titlesMainDocument", "collations", "volumeIssues",
+ "periodicals", "meetings", "subjectMeetings", "series",
+ "authors", "subjectPersons", "urls")