1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# -*- coding: UTF-8 -*-
import functools
from django.conf import settings
from gm_rpcd.all import context, bind
from gm_rpcd.internals.dynamic_scopes import DynamicVariableUnboundError
from helios.rpc import create_default_invoker
from utils.rpc import logging_exception, gen
from gm_types.error import ERROR as CODES
rpc_invoker = create_default_invoker(debug=settings.DEBUG)
def get_current_rpc_invoker():
try:
return context.rpc
except DynamicVariableUnboundError:
return rpc_invoker
class RPCMixin(object):
@classmethod
def call_rpc(cls, api_endpoint, **kwargs):
"""call rpc.
get rpc invoker from current ctx, this method only support call rpc sequentially.
"""
r = get_current_rpc_invoker()
result = r[api_endpoint](**kwargs)
return result.unwrap()
def get_objects_from_queryset_and_pk_list(queryset, pk_list):
qs_objects = queryset.filter(pk__in=pk_list)
obj_map = {o.pk: o for o in qs_objects}
return [
obj_map[pk]
for pk in pk_list
if pk in obj_map
]
def bind_context(endpoint, **kwargs):
def _wrap(func):
@functools.wraps(func)
def _wrapper(*args, **kwargs):
return func(context, *args, **kwargs)
return bind(endpoint)(_wrapper)
return _wrap
def to_dict(obj, fields=None, excludes=None, expands=None):
ret = {}
model_fields = []
for field in obj._meta.get_fields():
field_name = field.name
model_fields.append(field_name)
if (excludes is not None and field_name in excludes) or \
(fields is not None and field_name not in fields):
# skip field that in the excludes or not in ther fields
continue
try:
fval = getattr(obj, field_name, None)
except:
fval = None
if not isinstance(field, models.fields.related.RelatedField) or not fval:
# Basic Field, get value directly
ret[field_name] = _get_val(fval)
else:
if expands is None or field_name not in expands.keys():
if isinstance(field, models.ForeignKey):
ret[field_name] = fval.id if fval else None
else:
# ManyToManyField
ret[field_name] = list(fval.values_list('id', flat=True))
else:
# need expand related object
related_fields = expands[field_name]
if isinstance(field, models.ForeignKey):
ret[field_name] = _fetch_related(fval, related_fields)
else:
# ManyToManyField
ret[field_name] = [
_fetch_related(o, related_fields) for o in fval.all()
]
# access the field not a Model's Field
if fields:
for field_name in set(fields) - set(model_fields):
field_list = field_name.split('__')
if len(field_list) > 1:
fval = obj
for i in field_list:
if fval is None:
break
try:
fval = getattr(fval, i, None)
except:
break
else:
fval = get_non_model_field_value(obj, field_name)
ret[field_name] = _get_val(fval)
return ret