def choices(self, cl): model_options = (self.field_model._meta.app_label, self.field_model._meta.model_name) model = get_field_by_relation_path(self.model, self.field_path).model widget_options = { 'id': 'id_{}'.format(self.field_path), 'query-ajax-url': reverse('autocomplete-list', kwargs={ 'app': model._meta.app_label, 'model': model.__name__, 'field': self.field.name }) + '?prepend-empty=true', 'multi': True, 'detailsurl': reverse('admin:{}_{}_autocomplete_details'.format(*model_options)), } return ({ 'value': self.value(), 'attrs': flatatt(widget_options), 'name': self.field_path, 'related_url': self.get_related_url(), 'search_fields_info': "Search by: {}".format(self.title), 'prefetch_data': self.get_prefetch_data(), }, )
def _get_history_dict(data, instance, runned_funcs): history = {} for func in runned_funcs: defaults = { key.split('__')[1]: value for key, value in data.items() if key.startswith(func.__name__) } for k, v in defaults.items(): if func.form_fields[k].get('exclude_from_history', False): continue value = v try: field = get_field_by_relation_path(instance, k) if isinstance(field, models.ForeignKey): value = str(field.rel.to.objects.get(pk=v)) field_name = field.verbose_name elif isinstance(field, models.ManyToOneRel): value = ', '.join(map(str, v)) field_name = v.model._meta.verbose_name_plural else: field_name = field.verbose_name except FieldDoesNotExist: field = func.form_fields[k]['field'] if isinstance(field, forms.ModelChoiceField): value = str(v) elif isinstance(field, forms.ChoiceField): value = dict(field.choices).get(int(v)) field_name = field.label history[str(field_name)] = value return history
def get_field_value(self, item, field): """ Returns the value for the given field name. Looking in: If the field is type Choices returns choice name else returns the value of row :param item: row from dict :param field: field name """ value = None if hasattr(self, field): value = getattr(self, field)(item) else: value = getattr_dunder(item, field) try: choice_class = get_field_by_relation_path( item._meta.model, field ).choices except FieldDoesNotExist: choice_class = None if ( use_choices and choice_class and isinstance(choice_class, Choices) ): value = choice_class.name_from_id(value) return value
def initialize_search_form(model, context): """ Add extra variables (search_fields, search_url) which are used by search form to template's context. Args: context (dict): context from view """ model_admin = ralph_site._registry[model] verbose_search_fields = [] admin_search_fields = model_admin.search_fields for field_name in admin_search_fields: try: field = get_field_by_relation_path(model, field_name) except FieldDoesNotExist: verbose_search_fields.append(field_name.split('__')[-1]) else: verbose_search_fields.append(field.verbose_name) context['search_fields'] = sorted(set(verbose_search_fields)) context['model_verbose_name'] = model._meta.verbose_name context['search_url'] = reverse( 'admin:{app_label}_{model_name}_changelist'.format( app_label=model._meta.app_label, model_name=model._meta.model_name, ))
def get_verbose_name(obj, name): """ Return verbose name from Django Model. Example: {{ obj|get_verbose_name:"my_field" }} """ return get_field_by_relation_path(obj, name).verbose_name
def _get_model_search_fields(self, model): """Gets `model`'s search fields.""" search_fields_tooltip = defaultdict(list) for field_name in self.admin_site._registry[model].search_fields: try: field = get_field_by_relation_path(model, field_name) key = str(model._meta.verbose_name) search_fields_tooltip[key].append(str(field.verbose_name)) except FieldDoesNotExist as e: logger.error(e) return search_fields_tooltip
def _get_content_type_from_field_path(model, field_path): # TODO: add some validator for it # TODO: store fields in some field in meta, not "calculate" # it every time field = get_field_by_relation_path(model, field_path) if isinstance(field, OneToOneRel): related_model = field.related_model else: related_model = field.rel.to content_type = ContentType.objects.get_for_model(related_model) return content_type
def normalize_value(model_class, label, value): """Convert value to Python's type based on value.""" field = get_field_by_relation_path(model_class, label) if isinstance(field, ChoiceField): choices = field.choice_class() try: value = [i[0] for i in choices if i[1] == value].pop() except IndexError: # NOTE(romcheg): Choice not found for the filter value. # Leaving it as is. pass elif isinstance(field, BooleanField): value = field.to_python(value) return value
def autocomplete_tooltip(self): empty_element = '<empty>' tooltip = [] for field in self.autocomplete_tooltip_fields: try: model_field = get_field_by_relation_path(self, field) except FieldDoesNotExist: logger.warning( 'Autocomplete tooltip field %s not found for %s', field, self._meta.model_name) continue value = get_value_by_relation_path(self, field) if isinstance(model_field.choices, Choices): value = model_field.choices.name_from_id(value) label = str(model_field.verbose_name) if isinstance(value, Manager): value = ', '.join(map(str, value.all())) tooltip.append('{}: {}'.format(label.capitalize(), value or empty_element)) return '\n'.join(tooltip)
if not content_type or content_type not in get_host_content_types(): return publish_host_update(instance.object) api_post_create.connect(custom_field_change) api_post_update.connect(custom_field_change) # trigger publish_host_update when related model change for model_path in [ 'configuration_path', 'configuration_path__module', 'ethernet_set', 'ethernet_set__ipaddress', ]: field = get_field_by_relation_path(BaseObject, model_path) model = get_model_from_relation(field) logger.debug('Setting up handler for {} change of BaseObject'.format( model.__name__, )) post_commit( # use wraps for keep magic attributes of func like __name__ wraps(publish_host_update_from_related_model)( partial( publish_host_update_from_related_model, field_path=model_path ) ), model )
def test_raise_exception_when_no_field(self): fake_field = 'device_info__fortunately_unexisting_deprecated_field' with self.assertRaises(FieldDoesNotExist): found = get_field_by_relation_path(Asset, fake_field)
def test_return_ok_when_long_path(self): found = get_field_by_relation_path(Asset, 'model__manufacturer__name') self.assertEqual(found, Manufacturer._meta.get_field('name'))
def test_return_ok_when_simply_field(self): field_name = 'barcode' found = get_field_by_relation_path(Asset, field_name) self.assertEqual(found, Asset._meta.get_field(field_name))