def label_for_field(name, model, model_admin=None, return_attr=False): attr = None try: label = model._meta.get_field_by_name(name)[0].verbose_name except models.FieldDoesNotExist: if name == "__unicode__": label = force_unicode(model._meta.verbose_name) elif name == "__str__": label = smart_str(model._meta.verbose_name) else: if callable(name): attr = name elif model_admin is not None and hasattr(model_admin, name): attr = getattr(model_admin, name) elif hasattr(model, name): attr = getattr(model, name) else: message = "Unable to lookup '%s' on %s" % (name, model._meta.object_name) if model_admin: message += " or %s" % (model_admin.__name__,) raise AttributeError(message) if hasattr(attr, "short_description"): label = attr.short_description elif callable(attr): if attr.__name__ == "<lambda>": label = "--" else: label = pretty_name(attr.__name__) else: label = pretty_name(name) if return_attr: return (label, attr) else: return label
def get_model_method_or_property_data(field_name, model, fun_kwargs): from is_core.forms.widgets import ReadonlyWidget class_method = get_class_method(model, field_name) method = (getattr(model, field_name) if hasattr(model, field_name) and not class_method and is_callable(getattr(model, field_name)) else class_method) if method: if hasattr(method, 'field'): # Generic relation label = getattr(method.field, 'verbose_name', pretty_name(field_name)) else: label = getattr(method, 'short_description', pretty_name(field_name)) try: return ((None, label, ReadonlyWidget) if isinstance(model, type) else (_get_method_or_property_value(method, field_name, model, fun_kwargs), label, ReadonlyWidget)) except InvalidMethodArguments: return None elif hasattr(model, field_name): return (getattr(model, field_name), pretty_name(field_name), ReadonlyWidget) else: return None
class OrderItemMaterialForm(forms.ModelForm): """Custom form for the OrderItem inline""" meta = OrderItemMaterial._meta # Setting "required" is superfluous if TabularInlineForm is used, but just in case that changes... # Do not use NumberInput. The size is uncontrollable. (HTML5 "new and improved") discount = forms.FloatField(widget=widgets.TextInput(attrs={'size': '5'}), label=pretty_name( label_for_field('discount', OrderItemMaterial)), required=not meta.get_field('discount').blank) tax = forms.FloatField(widget=widgets.TextInput(attrs={'size': '5'}), label=pretty_name( label_for_field('tax', OrderItemMaterial)), required=not meta.get_field('tax').blank) price_per_unit = forms.FloatField( widget=widgets.TextInput(attrs={'size': '10'}), label=pretty_name(label_for_field('price_per_unit', OrderItemMaterial)), required=not meta.get_field('price_per_unit').blank) class Meta: model = OrderItemMaterial fields = ["discount", "tax", "price_per_unit"]
def prepare_columns(self, queryset, columns, exclude): if columns: # When columns are specified, only use them as specified. new_columns = [] for column in columns: if isinstance(column, (list, tuple)): new_columns.append(column) else: # Get labels for what we can. if getattr(queryset, 'model', None): try: f = queryset.model._meta.get_field(column) new_columns.append([column, pretty_name(f.verbose_name)]) except FieldDoesNotExist: if callable(column): column_verbose = getattr(column, 'short_description', pretty_name(column.func_name)) else: attr = getattr(queryset.model, column, None) if attr is not None and callable(attr): column_verbose = getattr(attr, 'short_description', pretty_name(attr.func_name)) else: column_verbose = pretty_name(column) new_columns.append([column, column_verbose]) else: new_columns.append([column, pretty_name(column)]) return new_columns else: # Columns not known, pull them from the model. if hasattr(queryset, 'model'): return get_default_fields(queryset.model, (), exclude or None, include_verbose=True)
def label_for_field(name, model, model_admin=None, return_attr=False): """ Returns a sensible label for a field name. The name can be a callable, property (but not created with @property decorator) or the name of an object's attribute, as well as a genuine fields. If return_attr is True, the resolved attribute (which could be a callable) is also returned. This will be None if (and only if) the name refers to a field. """ attr = None try: field = model._meta.get_field_by_name(name)[0] try: label = field.verbose_name except AttributeError: # field is likely a RelatedObject label = field.opts.verbose_name except models.FieldDoesNotExist: if name == "__unicode__": label = force_text(model._meta.verbose_name) attr = six.text_type elif name == "__str__": label = force_str(model._meta.verbose_name) attr = bytes else: if callable(name): attr = name elif model_admin is not None and hasattr(model_admin, name): attr = getattr(model_admin, name) elif hasattr(model, name): attr = getattr(model, name) else: message = "Unable to lookup '%s' on %s" % (name, model._meta.object_name) if model_admin: message += " or %s" % (model_admin.__class__.__name__,) raise AttributeError(message) if hasattr(attr, "short_description"): label = attr.short_description elif (isinstance(attr, property) and hasattr(attr, "fget") and hasattr(attr.fget, "short_description")): label = attr.fget.short_description elif callable(attr): if attr.__name__ == "<lambda>": label = "--" else: label = pretty_name(attr.__name__) else: label = pretty_name(name) if return_attr: return (label, attr) else: return label
def _get_field_label_from_model_method(self, model, field_name): method = get_class_method(model, field_name) if not method: return None elif hasattr(method, 'short_description'): return method.short_description elif hasattr(method, 'field'): # Generic relation return getattr(method.field, 'verbose_name', pretty_name(field_name)) else: return pretty_name(field_name)
def _get_field_label_from_model_method(self, model, field_name): method = get_class_method(model, field_name) if not method: return None elif hasattr(method, 'short_description'): return method.short_description elif hasattr(method, 'field'): # Generic relation return getattr(method.field, 'verbose_name', pretty_name(field_name)) else: return pretty_name(field_name)
def _get_attr_label(owner, attr_name): attr = getattr(owner, attr_name) if hasattr(attr, "short_description"): return attr.short_description elif isinstance(attr, property) and hasattr(attr, "fget"): if hasattr(attr.fget, "short_description"): return attr.fget.short_description else: return pretty_name(attr.fget.__name__) elif callable(attr): return "--" if attr.__name__ == "<lambda>" else pretty_name(attr.__name__) else: return attr_name
def label_for_field(name, model, model_admin=None, return_attr=False): """ Returns a sensible label for a field name. The name can be a callable or the name of an object attributes, as well as a genuine fields. If return_attr is True, the resolved attribute (which could be a callable) is also returned. This will be None if (and only if) the name refers to a field. """ name_split = name.split('.') name = name_split[0] attr = None try: field = model._meta.get_field_by_name(name)[0] if isinstance(field, RelatedObject): label = field.opts.verbose_name else: label = field.verbose_name except models.FieldDoesNotExist: if name == "__unicode__": label = force_unicode(model._meta.verbose_name) attr = unicode elif name == "__str__": label = smart_str(model._meta.verbose_name) attr = str else: if callable(name): attr = name elif model_admin is not None and hasattr(model_admin, name): attr = getattr(model_admin, name) elif hasattr(model, name): attr = getattr(model, name) else: message = "Unable to lookup '%s' on %s" % ( name, model._meta.object_name) if model_admin: message += " or %s" % (model_admin.__class__.__name__,) raise AttributeError(message) if hasattr(attr, "short_description"): label = attr.short_description elif callable(attr): if attr.__name__ == "<lambda>": label = "--" else: label = pretty_name(attr.__name__) else: label = pretty_name(name) if return_attr: return (label, attr) else: return label
def make_sortfield_choices(field_dict, value_prefix=None, label_prefix=None, recursed=False): "If recursed is True, we're already in a sub-choices group." if not label_prefix is None: label_prefix += ': ' else: label_prefix = '' sort_choices = [] for fieldname, field in field_dict.items(): label = field.label if label is None: label = pretty_name(fieldname) else: label = unicode(label) label = label_prefix + label if hasattr(field, 'sort_choices'): subchoices = field.sort_choices( value_prefix= value_prefix, label_prefix= label, ) if not recursed: sort_choices.append( (label, subchoices), ) else: sort_choices += subchoices continue value = fieldname if not value_prefix is None: value = value_prefix + '__' + value sort_choices.append((value, label)) return sort_choices
def template_choices(): app_name = os.path.basename(os.path.dirname(os.path.abspath(__file__))) templates = [] names = set() # project template dirs dirs = [os.path.join(dir, app_name) for dir in settings.TEMPLATE_DIRS if os.path.isdir(os.path.join(dir, app_name))] if not dirs: #application template dirs dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates', app_name) if os.path.isdir(dir): dirs.append(dir) for dir in dirs: found = glob.glob(os.path.join(dir, '*.html')) for tpl in found: dir, file = os.path.split(tpl) base, ext = os.path.splitext(file) key, name = os.path.join(dir.split('/')[-1], file), pretty_name(base) if name not in names: names.add(name) templates.append((key, name)) return sorted(templates)
def _get_header_label(self, model, field_name): try: return model._meta.get_field(field_name).verbose_name except FieldDoesNotExist: method = get_class_method(model, field_name) return getattr(method, 'short_description', pretty_name(field_name))
def result_headers(cl): lookup_opts = cl.lookup_opts for i, field_name in enumerate(cl.list_display): header, attr = label_for_field(field_name, cl.model, model_admin=cl.model_admin, return_attr=True) if attr: # if the field is the action checkbox: no sorting and special class if field_name == "action_checkbox": yield {"text": header, "class_attrib": mark_safe(' class="action-checkbox-column"')} continue header = pretty_name(header) # It is a non-field, but perhaps one that is sortable admin_order_field = getattr(attr, "admin_order_field", None) if not admin_order_field: yield {"text": header} continue # So this _is_ a sortable non-field. Go to the yield # after the else clause. else: admin_order_field = None th_classes = [] new_order_type = "asc" if field_name == cl.order_field or admin_order_field == cl.order_field: th_classes.append("sorted %sending" % cl.order_type.lower()) new_order_type = {"asc": "desc", "desc": "asc"}[cl.order_type.lower()] yield { "text": header, "sortable": True, "url": cl.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}), "class_attrib": mark_safe(th_classes and ' class="%s"' % " ".join(th_classes) or ""), }
def column(col, obj=None): if obj is None: if isinstance(col, basestring): header = col else: try: header = getattr(col, 'short_description', col.__name__) except AttributeError: header = force_unicode(col) return pretty_name(header) else: if isinstance(col, basestring): try: value = getattr(obj, col) except AttributeError: value = '' if callable(value): try: value = value() except TypeError: value = '' elif callable(col): try: value = col(obj) except TypeError: value = '' else: value = '' return value
def validate_unique(self): """ Validates unique constrains on the document. unique_with is not checked at the moment. """ errors = [] exclude = self._get_validation_exclusions() for f in self.instance._fields.itervalues(): if f.unique and f.name not in exclude: filter_kwargs = { f.name: getattr(self.instance, f.name) } qs = self.instance.__class__.objects().filter(**filter_kwargs) # Exclude the current object from the query if we are editing an # instance (as opposed to creating a new one) if self.instance.pk is not None: qs = qs.filter(pk__ne=self.instance.pk) if len(qs) > 0: message = _(u"%(model_name)s with this %(field_label)s already exists.") % { 'model_name': unicode(capfirst(self.instance._meta.verbose_name)), 'field_label': unicode(pretty_name(f.name)) } err_dict = {f.name: [message]} self._update_errors(err_dict) errors.append(err_dict) return errors
def _get_resource_label(self, model, field_name): resource = self.get_resource(model) if resource: method_field = resource.get_method_returning_field_value(field_name) return getattr(method_field, 'short_description', pretty_name(field_name)) if method_field else None else: return None
def format_chanes(new, is_staff): result = [] for field in new: if not is_staff and field in settings.TICKET_NON_PUBLIC_FIELDS: continue result.append('%s: %s' % (pretty_name(field), new[field])) return '\n'.join(result)
def __init__(self, id, name=None, position=0, template_name=None): self.id = id if name is None: name = pretty_name(id) self.template_name = template_name or self.template_name self.name = name self.position = position super(Group, self).__init__()
class DispenseForm(forms.ModelForm): """ Custom entry form for the Dispensed admin """ support_item = ItemTypeDescChoiceField( queryset=Consumable.objects.select_related("item_type").order_by( "item_type__name", "description"), label=pretty_name(label_for_field('support_item', Dispensed))) consumer = NameLocationChoiceField( queryset=Hardware.objects.filter( item_type__consumer=True).select_related( "item_type", "last_assigned").order_by("description", "last_assigned__location"), label=pretty_name(label_for_field('consumer', Dispensed))) class Meta: model = Dispensed fields = ["support_item", "place_date", "consumer", "quantity"]
def get_field_tuple(name, form_or_model): """Returns a tuple for the field, of given instance, identified by "name". Instance could be a model instance, a form instance or any arbitrary object. The returned tuple is in the form: (label, attrs, value) """ name, sep, suffix = name.partition(':') label = "" value = "" td_attrs = {} field_list = get_fields(form_or_model) field = None if name in field_list: field = field_list[name] elif hasattr(form_or_model, name): field = getattr(form_or_model, name) if hasattr(field, 'short_description'): name = field.short_description if isinstance(field, models.Field): label = '%s:' % field.verbose_name value = '%s' % field_to_string(field, form_or_model) elif isinstance(field, forms.Field): bf = BoundField(form_or_model, field, name) label = '%s' % bf.label_tag() value = '%s' % bf if bf.help_text: value += '<br/><span title="%(help_text)s" class="helptext helppopup">%(help_text)s</span>' % { "help_text": '%s' % bf.help_text } errors = bf.errors if errors: value += '<br/>\n<ul class="errorlist">\n' for error in errors: value += '\t<li>%s</li>\n' % error value += '</ul>\n' css_classes = bf.css_classes() if css_classes: td_attrs['class'] = css_classes else: name = _(pretty_name(name).lower()) label = '%s:' % name.capitalize() value = field() if callable(field) else field firstcap_label = label[:1].upper() + label[1:] if suffix: value += " " + suffix return mark_safe(firstcap_label), flatatt(td_attrs), mark_safe(value)
def iterate_model_fields(model, order_by='name'): from app.detective import register from django.db.models.fields import FieldDoesNotExist models_rules = register.topics_rules().model(model) if hasattr(model, '__fields_order__'): _len = len(model._meta.fields) model_fields = sorted( model._meta.fields, key=lambda x: model.__fields_order__.index(x.name) if x.name in model.__fields_order__ else _len) else: model_fields = sorted(model._meta.fields, key=lambda el: getattr(el, order_by)) for f in model_fields: # Ignores field terminating by + or begining by _ if not f.name.endswith("+") and not f.name.endswith( "_set") and not f.name.startswith("_"): try: # Get the rules related to this model field_rules = models_rules.field(f.name).all() except FieldDoesNotExist: # No rules field_rules = [] field_type = f.get_internal_type() # Find related model for relation if field_type.lower() == "relationship": # We received a model as a string if type(f.target_model) is str: # Extract parts of the module path module_path = f.target_model.split(".") # Import models as a module module = __import__(".".join(module_path[0:-1]), fromlist=["class"]) # Import the target_model from the models module target_model = getattr(module, module_path[-1], {__name__: None}) else: target_model = f.target_model related_model = target_model.__name__ else: related_model = None verbose_name = getattr(f, "verbose_name", None) if verbose_name is None: # Use the name as verbose_name fallback verbose_name = pretty_name(f.name).lower() yield { 'name': f.name, 'type': field_type, 'direction': getattr(f, "direction", ""), 'rel_type': getattr(f, "rel_type", ""), 'help_text': getattr(f, "help_text", ""), 'verbose_name': verbose_name, 'related_model': related_model, 'model': model.__name__, 'rules': field_rules.copy() }
def add_metadata_headers(table, meta_data): for header in meta_data.headers: table.columns.add(field=header, visible=bool(header in visible_on_start), title=forms.pretty_name(header), align='left', sortable=True, halign='left', valign='middle')
def _get_field_label_from_model(self, model, resource, field_name): try: return self._get_field_label_from_model_field(model, field_name) except FieldDoesNotExist: return ( self._get_field_label_from_resource_method(resource, field_name) or self._get_field_label_from_model_method(model, field_name) or self._get_field_label_from_model_related_objects(model, field_name) or pretty_name(field_name) )
def __init__(self, name, field, Handler): self.field_name = name self.field = field self.Handler = Handler if hasattr(Handler, 'SEARCH_FIELD_NAMES') and name in Handler.SEARCH_FIELD_NAMES: prettyname = Handler.SEARCH_FIELD_NAMES[name] else: prettyname = pretty_name(self.field_name) self.pretty_field_name = prettyname
class OrderItemConsumableForm(forms.ModelForm): """Custom form for the consumable OrderItem inlines """ item = ItemTypeDescChoiceField( queryset=Consumable.objects.select_related("item_type").order_by( "item_type__name", "description"), label=pretty_name(label_for_field('item', OrderItemConsumable))) class Meta: model = OrderItemConsumable fields = ["completed", "department", "description", "quantity", "item"]
def get_field_tuple(name, form_or_model): """Returns a tuple for the field, of given instance, identified by "name". Instance could be a model instance, a form instance or any arbitrary object. The returned tuple is in the form: (label, attrs, value) """ name, sep, suffix = name.partition(':') label = "" value = "" td_attrs = {} field_list = get_fields(form_or_model) field = None if name in field_list: field = field_list[name] elif hasattr(form_or_model, name): field = getattr(form_or_model, name) if hasattr(field, 'short_description'): name = field.short_description if isinstance(field, models.Field): label = '%s:' % field.verbose_name value = '%s' % field_to_string(field, form_or_model) elif isinstance(field, forms.Field): bf = BoundField(form_or_model, field, name) label = '%s' % bf.label_tag() value = '%s' % bf if bf.help_text: value += '<br/><span title="%(help_text)s" class="helptext helppopup">%(help_text)s</span>' % {"help_text": '%s' % bf.help_text} errors = bf.errors if errors: value += '<br/>\n<ul class="errorlist">\n' for error in errors: value += '\t<li>%s</li>\n' % error value += '</ul>\n' css_classes = bf.css_classes() if css_classes: td_attrs['class'] = css_classes else: name = _(pretty_name(name).lower()) label = '%s:' % name.capitalize() value = field() if callable(field) else field firstcap_label = label[:1].upper() + label[1:] if suffix: value += " " + suffix return mark_safe(firstcap_label), flatatt(td_attrs), mark_safe(value)
def get_model_fields(model, order_by='name'): from app.detective import register from django.db.models.fields import FieldDoesNotExist fields = [] models_rules = register.topics_rules().model(model) # Create field object for f in model._meta.fields: # Ignores field terminating by + or begining by _ if not f.name.endswith("+") and not f.name.endswith("_set") and not f.name.startswith("_"): # Find related model for relation if f.get_internal_type().lower() == "relationship": # We received a model as a string if type(f.target_model) is str: # Extract parts of the module path module_path = f.target_model.split(".") # Import models as a module module = __import__( ".".join(module_path[0:-1]), fromlist=["class"]) # Import the target_model from the models module target_model = getattr(module, module_path[-1], {__name__: None}) else: target_model = f.target_model related_model = target_model.__name__ else: related_model = None try: # Get the rules related to this model field_rules = models_rules.field(f.name).all() except FieldDoesNotExist: # No rules field_rules = [] verbose_name = getattr(f, "verbose_name", None) if verbose_name is None: # Use the name as verbose_name fallback verbose_name = pretty_name(f.name) field = { 'name' : f.name, 'type' : f.get_internal_type(), 'direction' : getattr(f, "direction", ""), 'rel_type' : getattr(f, "rel_type", ""), 'help_text' : getattr(f, "help_text", ""), 'verbose_name' : verbose_name, 'related_model': related_model, 'model' : model.__name__, 'rules' : field_rules } fields.append(field) get_key=lambda el: el[order_by] fields = sorted(fields, key=get_key) return fields
def contact_cards(obj, concise=True): """ Get all the contact fields from a model or form and return them as cards """ # Get all the fields. Try as a form first, then as a model. if isinstance(obj, models.Model): fields = [(field.name, field) for field in obj._meta.fields] value_getter = lambda field_name: getattr(obj, field_name) elif isinstance(obj, (forms.Form, forms.ModelForm)): fields = [(name, field) for (name, field) in obj.fields.iteritems()] if obj.is_valid(): value_getter = lambda field_name: obj.cleaned_data[field_name] else: value_getter = lambda field_name: obj[field_name].value() else: return {} contact_card_dict = {} for field_name, field in filter( lambda (field_name, field): isinstance(field, BaseContactField), fields ): values = value_getter(field_name) contact_card_dict[field_name] = {} for group in field._valid_groups: contact_card_dict[field_name][group] = OrderedDict() for label in field._valid_labels: value = values.get(group, {}).get(label, '') display_name = field.label_format.format( field=unicode(field.display_name), group=unicode(field.group_display_names.get( group, pretty_name(group) )), label=unicode(field.label_display_names.get( label, pretty_name(label) )) ) if value or not concise: contact_card_dict[field_name][group][label] = { 'display_name': display_name, 'value': value }
def save(self, commit=True): scl = super(CreateForm, self).save(False) scl.slug = '{}/{}'.format(scl.maintainer.username, scl.name) scl.title = pretty_name(scl.name) scl.sync_copr_texts() os.makedirs(scl.get_repos_root()) scl.save() scl.sync_copr_repos() scl.add_auto_tags() scl.collaborators.add(scl.maintainer) return scl
def save(self, commit=True): self.instance.slug = '{}/{}'.format(self.instance.maintainer.get_username(), self.instance.name) self.instance.title = pretty_name(self.instance.name) self.instance.description = self.cleaned_data['copr'].description self.instance.instructions = self.cleaned_data['copr'].instructions os.makedirs(self.instance.get_repos_root()) self.instance.save() self.instance.coprs.add(self.cleaned_data['copr']) self.instance.add_auto_tags() self.instance.collaborators.add(self.instance.maintainer) return self.instance
def errors_to_messages(errors): messages = [] for field, error in errors.iteritems(): title = '<u>{0}</u> needs a correction:'.format(pretty_name(field)) title = mark_safe(title) messages.append({ 'title': title, 'contents': error.as_text().lstrip("* ").lower(), 'type': 'warning' }) return messages
def get_ordering_field(self): # Copied from django_filter. But in this context, uses floppyforms. if self._meta.order_by: if isinstance(self._meta.order_by, (list, tuple)): if isinstance(self._meta.order_by[0], (list, tuple)): # e.g. (('field', 'Display name'), ...) choices = [(f[0], f[1]) for f in self._meta.order_by] else: choices = [(f, _('%s (descending)' % pretty_name(f[1:])) if f[0] == '-' else pretty_name(f)) for f in self._meta.order_by] else: # add asc and desc field names # use the filter's label if provided choices = [] for f, fltr in self.filters.items(): choices.extend([ (fltr.name or f, fltr.label or pretty_name(f)), ("-%s" % (fltr.name or f), _('%s (descending)' % (fltr.label or pretty_name(f)))) ]) return forms.ChoiceField(label="Ordering", required=False, choices=choices)
class HelpdeskCallForm(forms.ModelForm): """ Custom form to get the supported items dropdown under control """ # Find the non-consumable items not currently assigned to an EOL department item = forms.ModelChoiceField(queryset=NonConsumable.objects.filter( department__end_of_life=False).order_by("tag_ver"), label=pretty_name( label_for_field('item', HelpdeskCall))) class Meta: model = HelpdeskCall fields = ["item"]
def get_fields(self, fields=None, exclude=[], bool_raw=False): if fields == None: fields = [field[0] for field in Worker._meta.get_fields_with_model()] data = [] for field in fields: field_name = field.name if field_name not in exclude: if hasattr(self, "get_"+field_name+"_display"): #has a display name data.append((pretty_name(field_name), getattr(self, "get_"+field_name+"_display"))) elif hasattr(self, field_name): if field.get_internal_type() == 'BooleanField' and not bool_raw: if getattr(self, field_name): word = "Yes" else: word = "No" data.append((pretty_name(field_name), word)) else: data.append((pretty_name(field_name), getattr(self, field_name))) return SortedDict(data)
def comma_separated_manager(attr_name): """ Returns a function which takes a M2M manager on an object and returns it as a comma separated string. """ def inner(self, obj): manager = getattr(obj, attr_name) return ", ".join([unicode(x) for x in manager.all()]) inner.short_description = pretty_name(attr_name) return inner
def label_for_field(name, model, model_admin=None, return_attr=False): attr = None if not isinstance(model, DocumentMetaWrapper): model._meta = DocumentMetaWrapper(model) try: field = model._meta.get_field_by_name(name)[0] label = field.name.replace('_', ' ') except FieldDoesNotExist: if name == "__unicode__": label = force_unicode(model._meta.verbose_name) elif name == "__str__": label = smart_str(model._meta.verbose_name) else: if isinstance(name, collections.Callable): attr = name elif model_admin is not None and hasattr(model_admin, name): attr = getattr(model_admin, name) elif hasattr(model, name): attr = getattr(model, name) else: message = "Unable to lookup '%s' on %s" % (name, model._meta.object_name) if model_admin: message += " or %s" % (model_admin.__class__.__name__,) raise AttributeError(message) if hasattr(attr, "short_description"): label = attr.short_description elif isinstance(attr, collections.Callable): if attr.__name__ == "<lambda>": label = "--" else: label = pretty_name(attr.__name__) else: label = pretty_name(name) if return_attr: return (label, attr) else: return label
def label_for_path(base_model, path, models, many, field='', links=False): label = label_for_model(base_model, links=True) if path: for i, n in enumerate(path): basic_n = u''.join(pretty_name(n).split()).lower() basic_modelname = u''.join( pretty_name(models[i + 1].__name__).split()).lower() if unicode(n).lower() == unicode(models[i + 1].__name__).lower(): label += u' \u2192 ' + label_for_model(models[i + 1], links=links) elif basic_n == basic_modelname or basic_n in basic_modelname or basic_modelname in basic_n: label += u' \u2192 ' + label_for_model( models[i + 1], name=pretty_name(n), links=links) else: label += u' \u2192 ' + label_for_model( models[i], name=pretty_name(n), h=n, links=links) + u' (' + label_for_model(models[i + 1], links=links) + u')' if field: label += u' \u2192 ' + label_for_model( models[-1], name=pretty_name(field), h=field, links=links) return mark_safe(label)
def formfield_for_manytomany(self, db_field, request=None, **kwargs): """ Get a form Field for a ManyToManyField. """ db = kwargs.get('using') if db_field.name in self.raw_id_fields: kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db) kwargs['help_text'] = '' elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)): kwargs['widget'] = widgets.FilteredSelectMultiple(pretty_name(db_field.name), (db_field.name in self.filter_vertical)) return db_field.formfield(**kwargs)
def _label(self, field): """ Returns a pretty name for the given field. First check is the label_overrides dict. Remaining checks follow the django admin's pattern (including, for example, short_description support.) """ if field in self.label_overrides: return self.label_overrides[field] try: return label_for_field(field, self.model, self) except AttributeError: # Trust that it exists, for now. return pretty_name(field)
def get_cls_or_inst_method_or_property_data(field_name, cls_or_inst, fun_kwargs): from is_core.forms.widgets import ReadonlyWidget class_method = get_class_method(cls_or_inst, field_name) method = ( getattr(cls_or_inst, field_name) if hasattr(cls_or_inst, field_name) and not class_method and is_callable(getattr(cls_or_inst, field_name)) else class_method ) if method: label = getattr(method, 'short_description', pretty_name(field_name)) try: return ( (None, label, ReadonlyWidget) if isinstance(cls_or_inst, type) else (get_callable_value_or_value(method, field_name, cls_or_inst, fun_kwargs), label, ReadonlyWidget) ) except InvalidMethodArguments: return None elif hasattr(cls_or_inst, field_name): return (getattr(cls_or_inst, field_name), pretty_name(field_name), ReadonlyWidget) else: return None
def validate_unique(self): """ Validates unique constrains on the document. unique_with is supported now. """ errors = [] exclude = self._get_validation_exclusions() for f in self.instance._fields.values(): if f.unique and f.name not in exclude: filter_kwargs = { f.name: getattr(self.instance, f.name), 'q_obj': None, } if f.unique_with: for u_with in f.unique_with: u_with_field = self.instance._fields[u_with] u_with_attr = getattr(self.instance, u_with) # handling ListField(ReferenceField()) sucks big time # What we need to do is construct a Q object that # queries for the pk of every list entry and only # accepts lists with the same length as our list if isinstance(u_with_field, ListField) and \ isinstance(u_with_field.field, ReferenceField): q_list = [Q(**{u_with: k.pk}) for k in u_with_attr] q = reduce(lambda x, y: x & y, q_list) size_key = '%s__size' % u_with q = q & Q(**{size_key: len(u_with_attr)}) filter_kwargs['q_obj'] = q & filter_kwargs['q_obj'] else: filter_kwargs[u_with] = u_with_attr qs = self.instance.__class__.objects.clone() qs = qs.no_dereference().filter(**filter_kwargs) # Exclude the current object from the query if we are editing # an instance (as opposed to creating a new one) if self.instance.pk is not None: qs = qs.filter(pk__ne=self.instance.pk) if qs.count() > 0: message = _("%s with this %s already exists.") % ( str(capfirst(self.instance._meta.verbose_name)), str(pretty_name(f.name)) ) err_dict = {f.name: [message]} self._update_errors(err_dict) errors.append(err_dict) return errors