34

I have something like this:

class ContactData(models.Model):
    name  = models.CharField(max_length=300, verbose_name=u"Name", help_text=u"Please enter your name...",null=True, blank=False)
    phone = models.CharField(max_length=300, verbose_name=u"Phone number", null=True, blank=False)

I would like to show a field's label and help_text in template (that is - just access it from view). Can this be done?

frnhr
  • 12,354
  • 9
  • 63
  • 90

6 Answers6

44
unicode(ContactData._meta.get_field('name').verbose_name)
unicode(ContactData._meta.get_field('name').help_text)

unicode(ContactData._meta.get_field('phone').verbose_name)
unicode(ContactData._meta.get_field('phone').help_text)
j0k
  • 22,600
  • 28
  • 79
  • 90
user1649195
  • 472
  • 5
  • 3
16

I know this is old, but it deserves a full answer that can be used in templates.

If you need to use it in a template, the preferred method is to add model methods that get these values, such as:

from django.db import models
from six import text_type

class ContactData(models.Model):
    name  = models.CharField(max_length=300, verbose_name=u"Name", help_text=u"Please enter your name...",null=True, blank=False)
    phone = models.CharField(max_length=300, verbose_name=u"Phone number", null=True, blank=False)

    def __get_label(self, field):
        return text_type(self._meta.get_field(field).verbose_name)

    def __get_help_text(self, field)
        return text_type(self._meta.get_field(field).help_text)

    @property
    def name_label(self):
        return self.__get_label('name')

    @property
    def name_help_text(self):
        return self.__get_help_text('name')

    @property
    def phone_label(self):
        return self.__get_label('phone')

    @property
    def phone_help_text(self):
        return self.__get_help_text('phone')

Then, let us say instance is your object in a template, this is your label

<label for="id_phone">{{ instance.phone_label }}</label>
<div id="id_phone">{{ instance.phone }}</div>

Alternatively, you could create a template tag to do this, but the model method is clearer and keeps the model self contained.

three_pineapples
  • 11,579
  • 5
  • 38
  • 75
miigotu
  • 1,387
  • 15
  • 15
  • 1
    Oof. You end up doing a method for every field in the model! – mlissner Jan 28 '19 at 23:55
  • 1
    You could use a generator function that will generate all of these methods with 3 lines, but for this question, it is better to illustrate the process with verbosity. – miigotu Mar 22 '20 at 12:23
  • @miigotu You took the words outta my mouth! I was thinking a good use case of this solution would be a mixin, which would add properties for any help text and what I will call "choice" fields, meaning any field where "choices" is passed to its constructor. – MikeyE Apr 24 '20 at 00:45
2

Try this.

model_instance.name.field.help_text
Fitoria
  • 605
  • 6
  • 13
  • 1
    I get `AttributeError: 'unicode' object has no attribute 'field'` for `model_instance.name.field` – frnhr Nov 28 '10 at 11:20
  • Tried this with Django 2.0 - but in a template, nowadays, this data is not available... – Henning Mar 12 '18 at 12:20
1

django-etc application has model_field_verbose_name and model_field_help_text template tags to access the data you asked from templates: http://django-etc.rtfd.org/en/latest/models.html#model-field-template-tags

idle sign
  • 1,164
  • 1
  • 12
  • 19
1

Example from a view:

return render(
    request,
    'projects/create_edit_project.html',
    {
        'form': form,
        'model_field_meta_data': 
            extract_model_field_meta_data(form),
    }
)

extract_model_field_meta_data extracts help_text for each model field referenced by the ModelForm form:

def extract_model_field_meta_data(form):
    """ Extract meta-data from the data model fields the form is handling. """
    meta_data = dict()
    for field_name, field_data in form.base_fields.items():
        meta_data[field_name] = {
            'help_text': getattr(field_data, 'help_text', '')
        }
    return meta_data

Then in the template:

<p class="help-block">{{ model_field_meta_data.title.help_text }}</p>

title is a field in the model.

  • If you have a form you also have the labels already... But this could ab a simple workaround - even if it's not an editing view, you can create a form for an object and put it in the context to provise the verbose name – Henning Mar 12 '18 at 12:42
0

You can show this as follows:

>>> ContactData._meta.fields
[<django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: name>,
 <django.db.models.fields.CharField: phone>]
>>> ContactData._meta.fields[1].help_text
u'Please enter your name...'
Tony
  • 9,672
  • 3
  • 47
  • 75