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 |