def resolve_override(self, context, ignore_failures=False): if isinstance(self.var, Variable): try: self.var.resolve(context) except VariableDoesNotExist as e: if len(self.var.lookups) == 1: available = '\n '.join( sorted(context.flatten().keys())) raise VariableDoesNotExist( f'''{self.var} does not exist in context. Available top level variables: {available} ''') else: full_name = '.'.join(self.var.lookups) bit, current = e.params extra = '' if isinstance(current, dict): available_keys = '\n '.join( sorted(current.keys())) extra = f'\nYou can access keys in the dict by their name. Available keys:\n\n {available_keys}\n' error = f"dict does not have a key '{bit}', and does not have a member {bit}" else: name = f'{type(current).__module__}.{type(current).__name__}' error = f'{name} does not have a member {bit}' available = '\n '.join( sorted(x for x in dir(current) if not x.startswith('_'))) raise VariableDoesNotExist( f'''Tried looking up {full_name} in context {error} {extra} Available attributes: {available} The object was: {current!r} ''') return orig_resolve(self, context, ignore_failures)
def render(self, context): try: table = self.table_name.resolve(context) except VariableDoesNotExist: err = "Variable %s not found in context. Perhaps you forgot " \ "to pass it to the renderer?" % self.datable_name raise VariableDoesNotExist(err) opts = dict() opts['name'] = self.table_name opts['widgets'] = table.getStorage().getWidgets() opts['records_name'] = table.records_name opts['fields'] = [] ds = table.getStorage().defaultSort if ds: idx = table.getStorage().getColumnIndex(ds[0].getName()) + 1 if ds[1]: idx = 0 - idx opts['defaultSort'] = idx opts['image_formatter'] = False opts['image_formatter_max_width'] = 64 opts['image_formatter_max_height'] = 48 opts['href_formatter'] = False opts['nosort'] = set() for no, column in enumerate(table.storage.getColumns()): d = dict(name=column.getName(), label=column.getLabel(), editable='false', formatter=column.getFormatter()) if column.sortable == False: opts['nosort'].add(no + 1) if column.width is not None: if type(column.width) == int: d['width'] = '%ipx' % column.width elif type(column.width) == float: d['width'] = '%.0f%%' % column.width else: d['width'] = str(column.width) opts['fields'].append(d) return get_template(self.templateName).render(template.Context(opts))
def _resolve_lookup(self, context): """ Performs resolution of a real variable (i.e. not a literal) against the given context. As indicated by the method's name, this method is an implementation detail and shouldn't be called by external code. Use Variable.resolve() instead. """ current = context try: # catch-all for silent variable failures for bit in self.lookups: if callable(current): if getattr(current, 'alters_data', False): current = settings.TEMPLATE_STRING_IF_INVALID else: try: # method call (assuming no args required) current = current() except TypeError: # arguments *were* required # GOTCHA: This will also catch any TypeError # raised in the function itself. current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call try: # dictionary lookup current = current[bit] except (TypeError, AttributeError, KeyError): try: # attribute lookup current = getattr(current, bit) except (TypeError, AttributeError): try: # list-index lookup current = current[int(bit)] except ( IndexError, # list index out of range ValueError, # invalid literal for int() KeyError, # current is a dict without `int(bit)` key TypeError, # unsubscriptable object ): raise VariableDoesNotExist( "Failed lookup for key [%s] in %r", (bit, current)) # missing attribute except Exception, e: if getattr(e, 'silent_variable_failure', False): current = settings.TEMPLATE_STRING_IF_INVALID else: raise
def render(self, context): try: table = self.table_name.resolve(context) except VariableDoesNotExist: err = "Table named %s not found in context. Perhaps you forgot " \ "to pass it to the renderer?" % self.datable_name raise VariableDoesNotExist(err) widget = table.storage.getWidget(self.widget_name) if widget is None: raise Exception("There is no widget %s in table %s" \ % (self.widget_name, self.table_name)) opts = dict() opts['table'] = table opts['widget'] = widget opts['widget_id'] = 'w_%s_%s' % (table.name, widget.name) templateName = widget.templateName return get_template(widgetTemplatePath(templateName)).render( template.Context(opts))
def _my_resolve_lookup(self, context): """ Performs resolution of a real variable (i.e. not a literal) against the given context. As indicated by the method's name, this method is an implementation detail and shouldn"t be called by external code. Use Variable.resolve() instead. """ current = context try: # catch-all for silent variable failures for bit in self.lookups: try: # dictionary lookup current = current[bit] # ValueError/IndexError are for numpy.array lookup on # numpy < 1.9 and 1.9+ respectively except (TypeError, AttributeError, KeyError, ValueError, IndexError): try: # attribute lookup # Don"t return class attributes if the class is the context: if isinstance(current, BaseContext) and getattr( type(current), bit): raise AttributeError current = getattr(current, bit) except (TypeError, AttributeError) as e: # Reraise an AttributeError raised by a @property if (isinstance(e, AttributeError) and not isinstance(current, BaseContext) and bit in dir(current)): raise try: # list-index lookup current = current[int(bit)] except ( IndexError, # list index out of range ValueError, # invalid literal for int() KeyError, # current is a dict without `int(bit)` key TypeError): # unsubscriptable object raise VariableDoesNotExist( "Failed lookup for key " "[%s] in %r", (bit, current)) # missing attribute if callable(current): if getattr(current, "do_not_call_in_templates", False): pass elif getattr(current, "alters_data", False): try: current = context.template.engine.string_if_invalid except AttributeError: current = settings.TEMPLATE_STRING_IF_INVALID else: try: # method call (assuming no args required) current = current() except TypeError: try: inspect.getcallargs(current) except TypeError: # arguments *were* required try: current = context.template.engine.string_if_invalid # invalid method call except AttributeError: current = settings.TEMPLATE_STRING_IF_INVALID else: raise elif isinstance(current, Model): if ("request" in context) and hasattr(context["request"], "_ultracache"): # get_for_model itself is cached ct = ContentType.objects.get_for_model(current.__class__) context["request"]._ultracache.append((ct.id, current.pk)) except Exception as e: template_name = getattr(context, "template_name", None) or "unknown" if logger is not None: logger.debug( "Exception while resolving variable \"%s\" in template \"%s\".", bit, template_name, exc_info=True, ) if getattr(e, "silent_variable_failure", False): try: current = context.template.engine.string_if_invalid except AttributeError: current = settings.TEMPLATE_STRING_IF_INVALID else: raise return current
def test_str(self): exc = VariableDoesNotExist(msg='Failed lookup in %r', params=({ 'foo': 'bar' }, )) self.assertEqual(str(exc), "Failed lookup in {'foo': 'bar'}")