src/p4l/api/serializers.py
changeset 48 e2ccb0093452
parent 47 b07f8d11f2b8
child 93 c675183a9325
equal deleted inserted replaced
47:b07f8d11f2b8 48:e2ccb0093452
     3 Created on Sep 2, 2013
     3 Created on Sep 2, 2013
     4 
     4 
     5 @author: ymh
     5 @author: ymh
     6 '''
     6 '''
     7 from django.core.exceptions import ValidationError
     7 from django.core.exceptions import ValidationError
     8 from p4l.models import (Record, Title, Issn, Isbn, DocumentCode, Abstract,
     8 from p4l.models import Record
     9     AddedTitle, TitleMainDocument, Imprint, Collation, VolumeIssue, Periodical,
       
    10     Meeting, SubjectMeeting, Serie, Url)
       
    11 from rest_framework import serializers
     9 from rest_framework import serializers
    12 import logging
    10 import logging
       
    11 from rest_framework.serializers import NestedValidationError
       
    12 import copy
       
    13 from django.db.models.fields.related import ForeignKey
    13 
    14 
    14 logger = logging.getLogger(__name__)
    15 logger = logging.getLogger(__name__)
    15 
    16 
    16 class ThesaurusSerializer(serializers.SlugRelatedField):
    17 class ThesaurusSerializer(serializers.SlugRelatedField):
    17     
    18     
    30         except (TypeError, ValueError):
    31         except (TypeError, ValueError):
    31             msg = self.error_messages['invalid']
    32             msg = self.error_messages['invalid']
    32             raise ValidationError(msg)
    33             raise ValidationError(msg)
    33 
    34 
    34 
    35 
    35 class BaseTitleSerializer(serializers.ModelSerializer):
    36 class P4lModelSerializer(serializers.ModelSerializer):
    36     class Meta:
       
    37         fields = ('title', 'lang')
       
    38     
    37     
    39 class TitleSerializer(BaseTitleSerializer):    
    38     
    40     class Meta(BaseTitleSerializer.Meta):
    39     def get_nested_field(self, model_field, related_model, to_many):
    41         model = Title
    40         field_exclude = ()
       
    41         if model_field is None:
       
    42             fk = [f.name for f in related_model._meta.fields if (isinstance(f, ForeignKey) and f.rel.to == Record)][0]
       
    43             field_exclude = ('id', fk)
       
    44         class NestedModelSerializer(P4lModelSerializer):
       
    45             class Meta:
       
    46                 model = related_model
       
    47                 depth = self.opts.depth - 1
       
    48                 exclude = field_exclude
    42 
    49 
    43 class AddedTitleSerializer(BaseTitleSerializer):    
    50         return NestedModelSerializer(many=to_many)
    44     class Meta(BaseTitleSerializer.Meta):
       
    45         model = AddedTitle
       
    46 
    51 
    47 class TitleMainDocumentSerializer(BaseTitleSerializer):    
    52         
    48     class Meta(BaseTitleSerializer.Meta):
    53     def field_from_native(self, data, files, field_name, into):
    49         model = TitleMainDocument
    54         """
       
    55         Override default so that the serializer can be used as a writable
       
    56         nested field across relationships.
       
    57         """        
       
    58         if self.read_only:
       
    59             return
       
    60         
       
    61         try:
       
    62             value = data[field_name]
       
    63         except KeyError:
       
    64             if self.default is not None and not self.partial:
       
    65                 # Note: partial updates shouldn't set defaults
       
    66                 value = copy.deepcopy(self.default)
       
    67             else:
       
    68                 if self.required:
       
    69                     raise ValidationError(self.error_messages['required'])
       
    70                 return
    50 
    71 
    51 class IssnSerializer(serializers.ModelSerializer):
    72         # Set the serializer object if it exists
    52     class Meta:
    73         obj = getattr(self.parent.object, field_name) if self.parent.object else None
    53         model = Issn
       
    54         fields = ('issn', 'lang')
       
    55 
    74 
    56 class IsbnSerializer(serializers.ModelSerializer):
    75         if self.source == '*':
    57     class Meta:
    76             if value:
    58         model = Isbn
    77                 into.update(value)
    59         fields = ('isbn', 'lang')
    78         else:
       
    79             if value in (None, ''):
       
    80                 into[(self.source or field_name)] = None
       
    81             elif self.many and hasattr(value, '__iter__'):
       
    82                 obj.all().delete()
       
    83                 nested_items = []
       
    84                 for val in value:
       
    85                     kwargs = {
       
    86                         'instance': None,
       
    87                         'data': val,
       
    88                         'context': self.context,
       
    89                         'partial': self.partial,
       
    90                         'many': False
       
    91                     }
       
    92                     serializer = self.__class__(**kwargs)
       
    93                     nested_items.append(serializer.from_native(val, files))
       
    94                 into[self.source or field_name] = nested_items
       
    95             else:
       
    96                 kwargs = {
       
    97                     'instance': obj,
       
    98                     'data': value,
       
    99                     'context': self.context,
       
   100                     'partial': self.partial,
       
   101                     'many': self.many
       
   102                 }
       
   103                 serializer = self.__class__(**kwargs)
    60 
   104 
    61 class DocumentCodeSerializer(serializers.ModelSerializer):
   105                 if serializer.is_valid():
    62     class Meta:
   106                     into[self.source or field_name] = serializer.object
    63         model = DocumentCode
   107                 else:
    64         fields = ('documentCode', 'lang')
   108                     # Propagate errors up to our parent
    65         
   109                     raise NestedValidationError(serializer.errors)
    66 class AbstractSerializer(serializers.ModelSerializer):
       
    67     class Meta:
       
    68         model = Abstract
       
    69         fields = ('abstract', 'lang')
       
    70 
       
    71 class ImprintSerializer(serializers.ModelSerializer):
       
    72     class Meta:
       
    73         model = Imprint
       
    74         fields = ('imprintCity', 'publisher', 'imprintDate', 'lang')
       
    75 
       
    76 class CollationSerializer(serializers.ModelSerializer):
       
    77     class Meta:
       
    78         model = Collation
       
    79         fields = ('collation', 'lang')
       
    80 
       
    81 class VolumeIssueSerializer(serializers.ModelSerializer):
       
    82     class Meta:
       
    83         model = VolumeIssue
       
    84         fields = ('volume', 'number', 'lang')
       
    85 
       
    86 class PeriodicalSerializer(serializers.ModelSerializer):
       
    87     class Meta:
       
    88         model = Periodical
       
    89         fields = ('label', 'lang')
       
    90 
       
    91 class MeetingSerializer(serializers.ModelSerializer):
       
    92     class Meta:
       
    93         model = Meeting
       
    94         fields = ('label', 'meetingNumber', 'meetingPlace', 'meetingDate', 'meetingYear', 'lang')
       
    95 
       
    96 class SubjectMeetingSerializer(serializers.ModelSerializer):
       
    97     class Meta:
       
    98         model = SubjectMeeting
       
    99         fields = ('label', 'meetingNumber', 'meetingPlace', 'meetingDate', 'meetingYear')
       
   100 
       
   101 class SerieSerializer(serializers.ModelSerializer):
       
   102     class Meta:
       
   103         model = Serie
       
   104         fields = ('title', 'volume', 'lang')
       
   105 
       
   106 class UrlSerializer(serializers.ModelSerializer):
       
   107     class Meta:
       
   108         model = Url
       
   109         fields = ('address', 'display', 'accessLevel')
       
   110 
   110 
   111 
   111 
   112 class RecordSerializer(serializers.ModelSerializer):
   112 
       
   113 
       
   114 
       
   115 #class RecordSerializer(serializers.ModelSerializer):
       
   116 class RecordSerializer(P4lModelSerializer):
   113     '''
   117     '''
   114     Serializer for record
   118     Serializer for record
   115     '''
   119     '''
   116     language = ThesaurusSerializer(many=False, slug_field='uri') 
   120     language = ThesaurusSerializer(many=False, slug_field='uri') 
   117     otherLanguages = ThesaurusSerializer(many=True, slug_field='uri')
   121     otherLanguages = ThesaurusSerializer(many=True, slug_field='uri')
   119     themes = ThesaurusSerializer(many=True, slug_field='uri')
   123     themes = ThesaurusSerializer(many=True, slug_field='uri')
   120     countries = ThesaurusSerializer(many=True, slug_field='uri')
   124     countries = ThesaurusSerializer(many=True, slug_field='uri')
   121     projectNames = ThesaurusSerializer(many=True, slug_field='uri')
   125     projectNames = ThesaurusSerializer(many=True, slug_field='uri')
   122     subjectCorporateBodies = ThesaurusSerializer(many=True, slug_field='uri') 
   126     subjectCorporateBodies = ThesaurusSerializer(many=True, slug_field='uri') 
   123     corporateAuthors = ThesaurusSerializer(many=True, slug_field='uri')
   127     corporateAuthors = ThesaurusSerializer(many=True, slug_field='uri')
   124 #    titles = TitleSerializer(many=True, read_only=False)
       
   125 #    addedTitles = AddedTitleSerializer(many=True, read_only=False)
       
   126 #    issns = IssnSerializer(many=True, read_only=False)
       
   127 #    isbns = IsbnSerializer(many=True, read_only=False)
       
   128 #    documentCodes = DocumentCodeSerializer(many=True, read_only=False)
       
   129 #    abstracts = AbstractSerializer(many=True, read_only=False)
       
   130 #    titlesMainDocument = TitleMainDocumentSerializer(many=True, read_only=False)
       
   131 #    imprints = ImprintSerializer(many=True, read_only=False)
       
   132 #    collations = CollationSerializer(many=True, read_only=False)    
       
   133 #    volumeIssues = VolumeIssueSerializer(many=True, read_only=False)
       
   134 #    periodicals = PeriodicalSerializer(many=True, read_only=False)
       
   135 #    meetings = MeetingSerializer(many=True, read_only=False)
       
   136 #    subjectMeetings = SubjectMeetingSerializer(many=True, read_only=False)
       
   137 #    series = SerieSerializer(many=True, read_only=False)
       
   138 #    authors = serializers.SlugRelatedField(many=True, read_only=False, slug_field="name")
       
   139 #    subjectPersons = serializers.SlugRelatedField(many=True, read_only=False, slug_field="name")
       
   140 #    urls = UrlSerializer(many=True, read_only=False)
       
   141 
   128 
   142     class Meta:
   129     class Meta:
   143         model = Record
   130         model = Record
   144         depth = 1
   131         depth = 1
   145         read_only_fields = ('identifier', 'uri')
   132         read_only_fields = ('identifier', 'uri')
   146         fields = ("identifier", "uri", "subjects", "notes", "otherLanguages",
   133         fields = ("identifier", "uri", "subjects", "notes", "otherLanguages",
   147                   "language", "editionStatement", "recordType", "isDocumentPart",
   134                   "language", "editionStatement", "recordType", "isDocumentPart",
   148                   "isMultilingual", "themes", "countries", "projectNames", 
   135                   "isMultilingual", "themes", "countries", "projectNames", 
   149                   "subjectCorporateBodies", "corporateAuthors")
   136                   "subjectCorporateBodies", "corporateAuthors", "imprints",
   150 #         fields = (
   137                   "titles", "addedTitles", "issns", "isbns", "documentCodes",
   151 #                       "editionStatement", "recordType","isDocumentPart",
   138                   "abstracts", "titlesMainDocument", "collations", "volumeIssues",
   152 #                   "isMultilingual","subjects", "themes", "countries",
   139                   "periodicals", "meetings", "subjectMeetings", "series",
   153 #                   "projectNames", "subjectCorporateBodies", "corporateAuthors",
   140                   "authors", "subjectPersons", "urls")
   154 #                   "titles", "issns", "isbns", "documentCodes", "abstracts",
       
   155 #                   "addedTitles", "titlesMainDocument", "imprints",
       
   156 #                   "collations", "volumeIssues", "periodicals", "meetings",
       
   157 #                   "subjectMeetings", "series", "authors", "subjectPersons",
       
   158 #                   "urls")        
       
   159 
       
   160 
   141 
   161     
   142