1
1
import logging
2
- from typing import Any , Tuple , Type
2
+ from typing import Any , Dict , List , Tuple , Type
3
3
4
4
from django .db import models
5
5
from django .db .models .query import QuerySet
14
14
class CrudModel (object ):
15
15
def __init__ (self , model : Type [models .Model ]):
16
16
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
+ ]
17
22
18
- def __get_fields (self , payload : dict ) -> Tuple [dict , dict ]:
23
+ def __get_fields (self , payload : Dict ) -> Tuple [Dict , Dict ]:
19
24
m2m_fields = {}
20
25
local_fields = {}
21
26
for field in payload .keys ():
@@ -27,12 +32,12 @@ def __get_fields(self, payload: dict) -> Tuple[dict, dict]:
27
32
return local_fields , m2m_fields
28
33
29
34
# Define BASE CRUD
30
- def _crud_add_obj (self , ** payload : dict ) -> Any :
35
+ def _crud_add_obj (self , ** payload : Dict ) -> Any :
31
36
local_fields , m2m_fields = self .__get_fields (payload )
32
37
obj = self .model .objects .create (** local_fields )
33
38
if m2m_fields :
34
39
for field , value in m2m_fields .items ():
35
- if value and isinstance (value , list ):
40
+ if value and isinstance (value , List ):
36
41
m2m_f = getattr (obj , field )
37
42
m2m_f .set (value )
38
43
return obj
@@ -47,7 +52,7 @@ def _crud_del_obj(self, id: int) -> "BaseApiResponse":
47
52
{"Detail" : "Not found." }, message = "Not found."
48
53
) # pragma: no cover
49
54
50
- def _crud_update_obj (self , id : int , payload : dict ) -> "BaseApiResponse" :
55
+ def _crud_update_obj (self , id : int , payload : Dict ) -> "BaseApiResponse" :
51
56
local_fields , m2m_fields = self .__get_fields (payload )
52
57
try :
53
58
obj , created = self .model .objects .update_or_create (
@@ -64,7 +69,17 @@ def _crud_update_obj(self, id: int, payload: dict) -> "BaseApiResponse":
64
69
return BaseApiResponse ({"id" : obj .id , "created" : created })
65
70
66
71
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 ()
68
83
69
84
def _crud_get_objs_all (self , maximum : int = None , ** filters : Any ) -> Any :
70
85
"""
0 commit comments