11import logging
22from typing import Any , Dict , List , Tuple , Type
33
4- from django .db import models
4+ from django .db import models , transaction
55from django .db .models .query import QuerySet
66from ninja_extra .shortcuts import get_object_or_none
77
8+ from easy .exception import BaseAPIException
89from easy .response import BaseApiResponse
910
1011logger = logging .getLogger (__name__ )
@@ -19,7 +20,7 @@ def __init__(self, model: Type[models.Model]):
1920 if isinstance (_field , models .ManyToManyField )
2021 )
2122
22- def __separate_payload (self , payload : Dict ) -> Tuple [Dict , Dict ]:
23+ def _separate_payload (self , payload : Dict ) -> Tuple [Dict , Dict ]:
2324 m2m_fields = {}
2425 local_fields = {}
2526 for _field in payload .keys ():
@@ -35,22 +36,30 @@ def __separate_payload(self, payload: Dict) -> Tuple[Dict, Dict]:
3536 local_fields .update ({_field : payload [_field ]})
3637 return local_fields , m2m_fields
3738
39+ @staticmethod
40+ def _crud_set_m2m_obj (obj : models .Model , m2m_fields : Dict ) -> bool :
41+ if obj and m2m_fields :
42+ for _field , _value in m2m_fields .items ():
43+ if _value and isinstance (_value , List ):
44+ m2m_f = getattr (obj , _field )
45+ m2m_f .set (_value )
46+ return True
47+
3848 # Define BASE CRUD
49+ @transaction .atomic ()
3950 def _crud_add_obj (self , ** payload : Dict ) -> Any :
40- local_f_payload , m2m_f_payload = self .__separate_payload (payload )
51+ local_f_payload , m2m_f_payload = self ._separate_payload (payload )
52+
4153 # Create obj with local_fields payload
42- try :
43- obj = self .model .objects .create (** local_f_payload )
44- except Exception as e : # pragma: no cover
45- logger .error (f"Crud_add Error - { e } " , exc_info = True )
46- return BaseApiResponse (str (e ), message = "Add failed" , errno = 500 )
54+ obj = self .model .objects .create (** local_f_payload )
55+
4756 # Save obj with m2m_fields payload
48- if m2m_f_payload :
49- for _field , _value in m2m_f_payload . items ():
50- if _value and isinstance ( _value , List ) :
51- m2m_f = getattr ( obj , _field )
52- m2m_f . set ( _value )
53- return BaseApiResponse ({ "id" : obj . pk }, errno = 201 )
57+ set_m2m_status = self . _crud_set_m2m_obj ( obj , m2m_f_payload )
58+
59+ if obj and set_m2m_status :
60+ return obj . id
61+ else :
62+ return None
5463
5564 def _crud_del_obj (self , pk : int ) -> "BaseApiResponse" :
5665 obj = get_object_or_none (self .model , pk = pk )
@@ -60,27 +69,18 @@ def _crud_del_obj(self, pk: int) -> "BaseApiResponse":
6069 else :
6170 return BaseApiResponse ("Not Found." , errno = 404 )
6271
63- def _crud_update_obj (self , pk : int , payload : Dict ) -> "BaseApiResponse" :
64- local_fields , m2m_fields = self .__separate_payload (payload )
72+ @transaction .atomic ()
73+ def _crud_update_obj (self , pk : int , payload : Dict ) -> bool :
74+ local_fields , m2m_fields = self ._separate_payload (payload )
6575 if not self .model .objects .filter (pk = pk ).exists ():
66- return BaseApiResponse ( "Not Found." , errno = 404 )
76+ return False
6777 try :
6878 obj , _ = self .model .objects .update_or_create (pk = pk , defaults = local_fields )
6979 except Exception as e : # pragma: no cover
70- logger .error (f"Crud_update Error - { e } " , exc_info = True )
71- return BaseApiResponse (str (e ), message = "Update Failed" , errno = 500 )
72- if obj and m2m_fields :
73- for _field , _value in m2m_fields .items ():
74- if _value :
75- m2m_f = getattr (obj , _field )
76- try :
77- m2m_f .set (_value )
78- except Exception as e : # pragma: no cover
79- logger .error (f"Crud_update Error - { e } " , exc_info = True )
80- return BaseApiResponse (
81- str (e ), message = "Update Failed" , errno = 500
82- )
83- return BaseApiResponse ({"pk" : pk }, message = "Updated." )
80+ raise BaseAPIException (f"Update Error - { e } " )
81+
82+ set_m2m_status = self ._crud_set_m2m_obj (obj , m2m_fields )
83+ return bool (set_m2m_status and obj )
8484
8585 def _crud_get_obj (self , pk : int ) -> Any :
8686 if self .m2m_fields_list :
0 commit comments