11# -*- coding: utf-8 -*-
22
33from flask import Flask
4- from flask_rest_jsonapi import Api , ResourceDetail , ResourceList , ResourceRelationship , JsonApiException
4+ from flask_rest_jsonapi import Api , ResourceDetail , ResourceList , ResourceRelationship
5+ from flask_rest_jsonapi .exceptions import ObjectNotFound
56from flask_sqlalchemy import SQLAlchemy
67from sqlalchemy .orm .exc import NoResultFound
78from marshmallow_jsonapi .flask import Schema , Relationship
2122class Person (db .Model ):
2223 id = db .Column (db .Integer , primary_key = True )
2324 name = db .Column (db .String )
25+ email = db .Column (db .String )
2426 birth_date = db .Column (db .Date )
27+ password = db .Column (db .String )
2528
2629
2730class Computer (db .Model ):
@@ -42,8 +45,10 @@ class Meta:
4245 self_view_many = 'person_list'
4346
4447 id = fields .Str (dump_only = True )
45- name = fields .Str ()
48+ name = fields .Str (requried = True , load_only = True )
49+ email = fields .Email (load_only = True )
4650 birth_date = fields .Date ()
51+ display_name = fields .Function (lambda obj : "{} <{}>" .format (obj .name .upper (), obj .email ))
4752 computers = Relationship (self_view = 'person_computers' ,
4853 self_view_kwargs = {'id' : '<id>' },
4954 related_view = 'computer_list' ,
@@ -60,7 +65,14 @@ class Meta:
6065 self_view_kwargs = {'id' : '<id>' }
6166
6267 id = fields .Str (dump_only = True )
63- serial = fields .Str ()
68+ serial = fields .Str (requried = True )
69+ owner = Relationship (attribute = 'person' ,
70+ self_view = 'computer_person' ,
71+ self_view_kwargs = {'id' : '<id>' },
72+ related_view = 'person_detail' ,
73+ related_view_kwargs = {'computer_id' : '<id>' },
74+ schema = 'PersonSchema' ,
75+ type_ = 'person' )
6476
6577
6678# Create resource managers
@@ -71,9 +83,23 @@ class PersonList(ResourceList):
7183
7284
7385class PersonDetail (ResourceDetail ):
86+ def before_get_object (self , view_kwargs ):
87+ if view_kwargs .get ('computer_id' ) is not None :
88+ try :
89+ computer = self .session .query (Computer ).filter_by (id = view_kwargs ['computer_id' ]).one ()
90+ except NoResultFound :
91+ raise ObjectNotFound ({'parameter' : 'computer_id' },
92+ "Computer: {} not found" .format (view_kwargs ['computer_id' ]))
93+ else :
94+ if computer .person is not None :
95+ view_kwargs ['id' ] = computer .person .id
96+ else :
97+ view_kwargs ['id' ] = None
98+
7499 schema = PersonSchema
75100 data_layer = {'session' : db .session ,
76- 'model' : Person }
101+ 'model' : Person ,
102+ 'methods' : {'before_get_object' : before_get_object }}
77103
78104
79105class PersonRelationship (ResourceRelationship ):
@@ -83,23 +109,21 @@ class PersonRelationship(ResourceRelationship):
83109
84110
85111class ComputerList (ResourceList ):
86- def query (self , ** view_kwargs ):
112+ def query (self , view_kwargs ):
87113 query_ = self .session .query (Computer )
88- if view_kwargs .get ('id' ) is not None :
89- query_ = query_ .join (Person ).filter (Person .id == view_kwargs ['id' ])
90- return query_
91-
92- def before_create_object (self , data , ** view_kwargs ):
93114 if view_kwargs .get ('id' ) is not None :
94115 try :
95- person = self .session .query (Person ).filter_by (id = view_kwargs ['id' ]).one ()
116+ self .session .query (Person ).filter_by (id = view_kwargs ['id' ]).one ()
96117 except NoResultFound :
97- raise JsonApiException ({'parameter' : 'id' },
98- 'Person: {} not found' .format (view_kwargs ['id' ]),
99- title = 'ObjectNotFound' ,
100- status = '404' )
118+ raise ObjectNotFound ({'parameter' : 'id' }, "Person: {} not found" .format (view_kwargs ['id' ]))
101119 else :
102- data ['person_id' ] = person .id
120+ query_ = query_ .join (Person ).filter (Person .id == view_kwargs ['id' ])
121+ return query_
122+
123+ def before_create_object (self , data , view_kwargs ):
124+ if view_kwargs .get ('id' ) is not None :
125+ person = self .session .query (Person ).filter_by (id = view_kwargs ['id' ]).one ()
126+ data ['person_id' ] = person .id
103127
104128 schema = ComputerSchema
105129 data_layer = {'session' : db .session ,
@@ -114,13 +138,20 @@ class ComputerDetail(ResourceDetail):
114138 'model' : Computer }
115139
116140
141+ class ComputerRelationship (ResourceRelationship ):
142+ schema = ComputerSchema
143+ data_layer = {'session' : db .session ,
144+ 'model' : Computer }
145+
146+
117147# Create endpoints
118148api = Api (app )
119149api .route (PersonList , 'person_list' , '/persons' )
120- api .route (PersonDetail , 'person_detail' , '/persons/<int:id>' )
150+ api .route (PersonDetail , 'person_detail' , '/persons/<int:id>' , '/computers/<int:computer_id>/owner' )
121151api .route (PersonRelationship , 'person_computers' , '/persons/<int:id>/relationships/computers' )
122152api .route (ComputerList , 'computer_list' , '/computers' , '/persons/<int:id>/computers' )
123153api .route (ComputerDetail , 'computer_detail' , '/computers/<int:id>' )
154+ api .route (ComputerRelationship , 'computer_person' , '/computers/<int:id>/relationships/owner' )
124155
125156if __name__ == '__main__' :
126157 # Start application
0 commit comments