I figured it out! I passed the widget name to the template:
class CustomWidget(Widget):
class Media:
js = ('http://code.jquery.com/jquery-1.10.2.js', 'custom_widget.js')
def render(self, name, value, attrs=None):
instance_list = [item[2] for item in self.choices]
obj_dict_list = [model_to_dict(obj) for obj in obj_list]
output = render_to_string('myapp/widgets/custom_widget.html', {
'widget_name': name,
'obj_list': obj_dict_list,
})
return mark_safe(output)
Created a hidden input field in the template, specifying the widget name for the name
attr:
<!-- myapp/widgets/custom_widget.html -->
<input type="hidden" name="{{ widget_name }}" value="some-initial-value" />
{% for obj in obj_list %}
{{ do_something_with_obj }}
{% endfor %}
<script>
// make {{ widget_name }} accessible to the included js on the widget
var widgetName = "{{ widget_name }}";
</script>
Using JavaScript/jQuery I changed the value
attr of the hidden input:
// custom_widget.js
(function() {
var hiddenInput = $("input[name='" + widgetName + "']");
if (someCondition) {
hiddenInput.val(newVal);
}
)();
Finally, in value_from_data
, get the value of the hidden input:
class CustomWidget(Widget):
...
def value_from_datadict(self, data, files, name):
return data.get(name, None)