11import logging
2- from typing import Any , Tuple , Type
2+ from typing import Any , Dict , List , Tuple , Type
33
44from django .db import models
55from django .db .models .query import QuerySet
1414class CrudModel (object ):
1515 def __init__ (self , model : Type [models .Model ]):
1616 self .model = model
17+ self .m2m_fields = [
18+ f
19+ for f in self .model ._meta .get_fields (include_hidden = True )
20+ if isinstance (f , models .ManyToManyField )
21+ ]
1722
18- def __get_fields (self , payload : dict ) -> Tuple [dict , dict ]:
23+ def __get_fields (self , payload : Dict ) -> Tuple [Dict , Dict ]:
1924 m2m_fields = {}
2025 local_fields = {}
2126 for field in payload .keys ():
@@ -27,12 +32,12 @@ def __get_fields(self, payload: dict) -> Tuple[dict, dict]:
2732 return local_fields , m2m_fields
2833
2934 # Define BASE CRUD
30- def _crud_add_obj (self , ** payload : dict ) -> Any :
35+ def _crud_add_obj (self , ** payload : Dict ) -> Any :
3136 local_fields , m2m_fields = self .__get_fields (payload )
3237 obj = self .model .objects .create (** local_fields )
3338 if m2m_fields :
3439 for field , value in m2m_fields .items ():
35- if value and isinstance (value , list ):
40+ if value and isinstance (value , List ):
3641 m2m_f = getattr (obj , field )
3742 m2m_f .set (value )
3843 return obj
@@ -47,7 +52,7 @@ def _crud_del_obj(self, id: int) -> "BaseApiResponse":
4752 {"Detail" : "Not found." }, message = "Not found."
4853 ) # pragma: no cover
4954
50- def _crud_update_obj (self , id : int , payload : dict ) -> "BaseApiResponse" :
55+ def _crud_update_obj (self , id : int , payload : Dict ) -> "BaseApiResponse" :
5156 local_fields , m2m_fields = self .__get_fields (payload )
5257 try :
5358 obj , created = self .model .objects .update_or_create (
@@ -64,7 +69,17 @@ def _crud_update_obj(self, id: int, payload: dict) -> "BaseApiResponse":
6469 return BaseApiResponse ({"id" : obj .id , "created" : created })
6570
6671 def _crud_get_obj (self , id : int ) -> Any :
67- return get_object_or_none (self .model , id = id )
72+ if self .m2m_fields :
73+ qs = self .model .objects .filter (id = id ).prefetch_related (
74+ self .m2m_fields [0 ].name
75+ )
76+ for f in self .m2m_fields [1 :]:
77+ qs = qs .prefetch_related (f .name )
78+ else :
79+ qs = self .model .objects .filter (id = id )
80+ if qs :
81+ return qs .first ()
82+ return BaseApiResponse ()
6883
6984 def _crud_get_objs_all (self , maximum : int = None , ** filters : Any ) -> Any :
7085 """
0 commit comments