1
+ from collections import UserDict
1
2
from django .urls import resolve
2
3
from urllib .parse import urlparse
3
4
4
5
from django .test import RequestFactory
5
6
6
7
PROTECTED_VARIABLES = [
7
8
"consumer" ,
9
+ "context" ,
8
10
"element" ,
11
+ "params" ,
9
12
"selectors" ,
10
13
"session" ,
11
14
"url" ,
12
15
]
13
16
14
17
18
+ class Context (UserDict ):
19
+ """
20
+ A dictionary that keeps track of whether it's been used as dictionary
21
+ or if values has been set with dot notation. We expect things to be set
22
+ in dot notation so a warning is issued until next major version (1.0)
23
+ """
24
+
25
+ def __init__ (self , * args , ** kwargs ):
26
+ super ().__init__ (* args , ** kwargs )
27
+ self ._attr_data = {}
28
+
29
+ def __getitem__ (self , key ):
30
+ data = self .__dict__
31
+ if (
32
+ data ["data" ].get (key , KeyError ) is KeyError
33
+ and data ["_attr_data" ].get (key , KeyError ) is KeyError
34
+ ):
35
+ raise KeyError (key )
36
+ return self .data .get (key ) or self ._attr_data .get (key )
37
+
38
+ def __setitem__ (self , key , item ):
39
+ if not self .__dict__ .get ("data" ):
40
+ self .__dict__ ["data" ] = {}
41
+ self .__dict__ ["data" ][key ] = item
42
+
43
+ def __getattr__ (self , key ):
44
+ if not self .__dict__ .get ("data" ):
45
+ self .__dict__ ["data" ] = {}
46
+ if not self .__dict__ .get ("_attr_data" ):
47
+ self .__dict__ ["_attr_data" ] = {}
48
+
49
+ if (
50
+ self .__dict__ ["data" ].get (key , KeyError ) is KeyError
51
+ and self .__dict__ ["_attr_data" ].get (key , KeyError ) is KeyError
52
+ ):
53
+ raise AttributeError (key )
54
+ result = self .data .get (key ) or self ._attr_data .get (key )
55
+ return result
56
+
57
+ def __setattr__ (self , key , value ):
58
+ if not self .__dict__ .get ("_attr_data" ):
59
+ self .__dict__ ["_attr_data" ] = {}
60
+ self .__dict__ ["_attr_data" ][key ] = value
61
+
62
+
15
63
class Reflex :
16
64
def __init__ (self , consumer , url , element , selectors , params ):
17
65
self .consumer = consumer
18
- self .url = url
66
+ self .context = Context ()
19
67
self .element = element
68
+ self .params = params
20
69
self .selectors = selectors
21
70
self .session = consumer .scope ["session" ]
22
- self .params = params
23
- self .context = {}
71
+ self .url = url
72
+
73
+ self ._init_run = True
24
74
25
75
def __repr__ (self ):
26
76
return f"<Reflex url: { self .url } , session: { self .get_channel_id ()} >"
27
77
78
+ def __setattr__ (self , name , value ):
79
+ if name in PROTECTED_VARIABLES and getattr (self , "_init_run" , None ):
80
+ raise ValueError ("This instance variable is used by the reflex." )
81
+ super ().__setattr__ (name , value )
82
+
28
83
def get_context_data (self , * args , ** kwargs ):
29
84
if self .context :
30
85
self .context .update (** kwargs )
@@ -44,8 +99,7 @@ def get_context_data(self, *args, **kwargs):
44
99
view .object_list = view .get_queryset ()
45
100
46
101
context = view .get_context_data (** {"stimulus_reflex" : True })
47
-
48
- self .context = context
102
+ self .context .update (context )
49
103
self .context .update (** kwargs )
50
104
return self .context
51
105
0 commit comments