Return 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 model field, including across related objects. If return_attr is True, also return the resolved attribute
(name, model, model_admin=None, return_attr=False, form=None)
| 356 | |
| 357 | |
| 358 | def label_for_field(name, model, model_admin=None, return_attr=False, form=None): |
| 359 | """ |
| 360 | Return a sensible label for a field name. The name can be a callable, |
| 361 | property (but not created with @property decorator), or the name of an |
| 362 | object's attribute, as well as a model field, including across related |
| 363 | objects. If return_attr is True, also return the resolved attribute |
| 364 | (which could be a callable). This will be None if (and only if) the name |
| 365 | refers to a field. |
| 366 | """ |
| 367 | attr = None |
| 368 | try: |
| 369 | field = _get_non_gfk_field(model._meta, name) |
| 370 | try: |
| 371 | label = field.verbose_name |
| 372 | except AttributeError: |
| 373 | # field is likely a ForeignObjectRel |
| 374 | label = field.related_model._meta.verbose_name |
| 375 | except FieldDoesNotExist: |
| 376 | if name == "__str__": |
| 377 | label = str(model._meta.verbose_name) |
| 378 | attr = str |
| 379 | else: |
| 380 | if callable(name): |
| 381 | attr = name |
| 382 | elif hasattr(model_admin, name): |
| 383 | attr = getattr(model_admin, name) |
| 384 | elif hasattr(model, name): |
| 385 | attr = getattr(model, name) |
| 386 | elif form and name in form.fields: |
| 387 | attr = form.fields[name] |
| 388 | else: |
| 389 | try: |
| 390 | attr = get_fields_from_path(model, name)[-1] |
| 391 | except (FieldDoesNotExist, NotRelationField): |
| 392 | message = f"Unable to lookup '{name}' on {model._meta.object_name}" |
| 393 | if model_admin: |
| 394 | message += f" or {model_admin.__class__.__name__}" |
| 395 | if form: |
| 396 | message += f" or {form.__class__.__name__}" |
| 397 | raise AttributeError(message) |
| 398 | |
| 399 | if hasattr(attr, "short_description"): |
| 400 | label = attr.short_description |
| 401 | elif ( |
| 402 | isinstance(attr, property) |
| 403 | and hasattr(attr, "fget") |
| 404 | and hasattr(attr.fget, "short_description") |
| 405 | ): |
| 406 | label = attr.fget.short_description |
| 407 | elif callable(attr): |
| 408 | if attr.__name__ == "<lambda>": |
| 409 | label = "--" |
| 410 | else: |
| 411 | label = pretty_name(attr.__name__) |
| 412 | else: |
| 413 | label = pretty_name(name) |
| 414 | except FieldIsAForeignKeyColumnName: |
| 415 | label = pretty_name(name) |