@@ -6,12 +6,16 @@ def __init__(
66 self ,
77 nodelist ,
88 field_context ,
9+ polymorphic_type ,
10+ polymorphic_types ,
911 dict_data : dict ,
1012 component : None ,
1113 parent_component = None ,
1214 ):
1315 self ._nodelist = nodelist
1416 self ._field_context = field_context
17+ self ._polymorphic_type = polymorphic_type
18+ self ._polymorphic_types = polymorphic_types
1519 self ._dict_data = dict_data
1620 self ._component = component
1721 self ._parent_component = parent_component
@@ -20,17 +24,27 @@ def __str__(self):
2024 return self .render ()
2125
2226 def render (self ):
27+ if self ._polymorphic_types :
28+ component_expression = self ._polymorphic_types [self ._polymorphic_type ]
29+ return self ._render (component_expression )
30+ else :
31+ component_expression = self ._component
32+ return self ._render (component_expression )
33+
34+ def _render (self , target ):
2335 from django_viewcomponent .component import Component
2436
25- if isinstance (self . _component , str ):
37+ if isinstance (target , str ):
2638 return self ._render_for_component_cls (
27- component_registry .get (self . _component ),
39+ component_registry .get (target ),
2840 )
29- elif not isinstance (self ._component , type ) and callable (self ._component ):
30- # self._component is function
31- callable_component = self ._component
41+ elif not isinstance (target , type ) and callable (target ):
42+ # target is function
43+ callable_component = target
44+ content = self ._nodelist .render (self ._field_context )
3245 result = callable_component (
3346 self = self ._parent_component ,
47+ content = content ,
3448 ** self ._dict_data ,
3549 )
3650
@@ -43,16 +57,16 @@ def render(self):
4357 raise ValueError (
4458 f"Callable slot component must return str or Component instance. Got { result } " ,
4559 )
46- elif isinstance (self . _component , type ) and issubclass (
47- self . _component ,
60+ elif isinstance (target , type ) and issubclass (
61+ target ,
4862 Component ,
4963 ):
50- # self._component is Component class
51- return self ._render_for_component_cls (self . _component )
52- elif self . _component is None :
64+ # target is Component class
65+ return self ._render_for_component_cls (target )
66+ elif target is None :
5367 return self ._nodelist .render (self ._field_context )
5468 else :
55- raise ValueError (f"Invalid component variable { self . _component } " )
69+ raise ValueError (f"Invalid component variable { target } " )
5670
5771 def _render_for_component_cls (self , component_cls ):
5872 component = component_cls (
@@ -62,29 +76,31 @@ def _render_for_component_cls(self, component_cls):
6276 return self ._render_for_component_instance (component )
6377
6478 def _render_for_component_instance (self , component ):
65- component .component_context = self ._parent_component . component_context
79+ component .component_context = self ._field_context
6680
6781 with component .component_context .push ():
68- updated_context = component .get_context_data ()
69-
7082 # create slot fields
7183 component .create_slot_fields ()
7284
73- component .content = self ._nodelist .render (updated_context )
85+ # render content first
86+ component .content = self ._nodelist .render (component .component_context )
7487
7588 component .check_slot_fields ()
7689
90+ updated_context = component .get_context_data ()
91+
7792 return component .render (updated_context )
7893
7994
8095class BaseSlotField :
8196 parent_component = None
8297
83- def __init__ (self , value = None , required = False , component = None , ** kwargs ):
84- self ._value = value
98+ def __init__ (self , required = False , component = None , types = None , ** kwargs ):
99+ self ._value = None
85100 self ._filled = False
86101 self ._required = required
87102 self ._component = component
103+ self ._types = types
88104
89105 @classmethod
90106 def initialize_fields (cls ):
@@ -104,15 +120,21 @@ def filled(self):
104120 def required (self ):
105121 return self ._required
106122
107- def handle_call (self , nodelist , context , ** kwargs ):
123+ @property
124+ def types (self ):
125+ return self ._types
126+
127+ def handle_call (self , nodelist , context , polymorphic_type , ** kwargs ):
108128 raise NotImplementedError ("You must implement the `handle_call` method." )
109129
110130
111131class RendersOneField (BaseSlotField ):
112- def handle_call (self , nodelist , context , ** kwargs ):
132+ def handle_call (self , nodelist , context , polymorphic_type , ** kwargs ):
113133 value_instance = FieldValue (
114134 nodelist = nodelist ,
115135 field_context = context ,
136+ polymorphic_type = polymorphic_type ,
137+ polymorphic_types = self .types ,
116138 dict_data = {** kwargs },
117139 component = self ._component ,
118140 parent_component = self .parent_component ,
@@ -134,10 +156,12 @@ def __iter__(self):
134156
135157
136158class RendersManyField (BaseSlotField ):
137- def handle_call (self , nodelist , context , ** kwargs ):
159+ def handle_call (self , nodelist , context , polymorphic_type , ** kwargs ):
138160 value_instance = FieldValue (
139161 nodelist = nodelist ,
140162 field_context = context ,
163+ polymorphic_type = polymorphic_type ,
164+ polymorphic_types = self .types ,
141165 dict_data = {** kwargs },
142166 component = self ._component ,
143167 parent_component = self .parent_component ,
0 commit comments