Real name instead of fieldname in form

After the response around my last post I am trying to change my totally manual templates for forms to simple form where I use {{ person_form }} etcetera.

I inmediately have problems. The first is that the model field name is shown in the form instead of the real (translated) name.

class Person(models.model):
    firstName = models.CharField(_('first name'), blank=True, max_length=60)
    nameAffix = models.CharField(_('affix'),  blank=True, max_length=6)
    familyName = models.CharField(_('family name'), blank=True, max_length=60)

and the view:

def create_person(request):
    field_order = ['firstName', 'nameAffix', 'familyName', 'gender', 'dateOfBirth']

    if request.method == 'POST':
        person_form = PersonModelForm(data = request.POST)
        phonenumber_form_set = PhoneNumberFormSet(data = request.POST)

        if person_form.is_valid() and phonenumber_form_set.is_valid():
            person = person_form.save()
            for form in phonenumber_form_set:
                if form.cleaned_data and form.cleaned_data.get("telephoneNumber"):
                    phonenumber=form.save()
                    person.telephoneNumbers.add(phonenumber)
            return redirect('person-list')
        else:
            person_form = PersonModelForm(data = request.POST)
            phonenumber_form_set = PhoneNumberFormSet(data = request.POST)
    else:
        person_form = PersonModelForm()
        phonenumber_form_set = PhoneNumberFormSet()

    context = {'person_form': person_form,
               'phonenumber_form_set': phonenumber_form_set}

    return render(request,
                  template_name="MyNetwork\\person_form_test.html",
                  context=context) 

And the tmplate:

{% extends 'main-template.html' %}
{% load i18n %}
{% load crispy_forms_tags %}

{% block content%}
    <form method="POST">
        {% csrf_token %}

        {{ person_form | crispy}}
        {{ phonenumber_form_set | crispy }}

        <input type="submit" value="Submit">

    </form>
{% endblock content %}

And the form:

class PersonModelForm(BaseModelForm):
#    prefix="person"

    firstName = forms.CharField(
        widget = forms.TextInput(attrs=
            {
                #"label":"TEST",
                "placeholder": _("First name"),
                "autofocus": "autofocus",
                "type": "text",
                "size": 30, # width in characters
                "maxLength": Person._meta.get_field('firstName').max_length,
            }
        ))

    nameAffix = forms.CharField(
        widget = forms.TextInput(attrs=
            {
                "placeholder": _("affix"),
                "type": "text",
                "size": 5, # width in characters
                "maxLength": Person._meta.get_field('nameAffix').max_length,
            }
        ))

 #Other fields omitted

field_order = ['firstName', 'nameAffix', 'familyName', 'gender', 'dateOfBirth']

    class Meta:
        model = Person
        fields = "__all__"

(I left out a few models inbetween)
The base model:

class BaseModelForm(ModelForm):

    extra_information = forms.CharField(
        widget = forms.Textarea(attrs=
            {
                "placeholder": _('extra information'),
                "type": "text",
                "rows": 3,
                "maxLength": BaseModel._meta.get_field('extra_information').max_length,
            }
        ))
    
    def __init__(self, *args, **kwargs):
        super(BaseModelForm, self).__init__(*args, **kwargs)
        self.fields['extra_information'].required = False
    
    class Meta:
        model = BaseModel
        fields = "__all__"

I found that showing the fieldname instead of the real name can be caused by:

  1. Not using the Meta property refering to the corresponding model
  2. By using forms.form instead of forms.modelform
  3. By manually renaming the fields

But I think I got that correct.

I stil get
image
instead of affix

Can anybody tell me what I do wrong?

I’m not sure I’m following what all the issues are that you’re trying to describe here.

Is Enabling localization of fields what you are looking for?

You may also want to review the section on Overriding the default fields to better understand the relationships between ā€œfields that you defineā€ and ā€œfields that the ModelForm generateā€. (Especially the green Note box at the end of that section.)

I am not able to show the name of a field. Instead the fieldname is shown.

So the model

firstName = models.CharField(_('first name'), blank=True, max_length=60)
nameAffix = models.CharField(_('affix'),  blank=True, max_length=6)
familyName = models.CharField(_('family name'), blank=True, max_length=60)

is shown as (result from {{form}})

The name of the model field is used instead of the name provided in _('name')

I want to see

(last is result from manual template creation and what I assumed to be normal behavour.

I expected the (translated) name to be used.

That is covered in the referenced docs on overriding default fields.

Don’t redefine the ModelField definition as form fields in the form, use the Meta attributes to customize the form field attributes.
e.g.
Instead of:

class MyForm(ModelForm):
    model_field = CharField(...)
    class Meta:
        model = MyModel
        fields = ['model_field']

do:

class MyForm(ModelForm):
    class Meta:
        model = MyModel
        fields = [ ... ]
        widgets = { ... }
        # And, if necessary:
        labels = { ... }
        help_texts = { ... }
        error_messages = { ... }
        # With any other Meta attributes as desired.

An aside: I would highly recommend explicitly passing verbose_name=_() instead of relying on positional arguments.

To me it’s not clear if _() means gettext() or gettext_lazy() in this context, which can make a big difference. That might be your problem?

This solves it all. Lots or bad coding to rewrite now :frowning: Thanks

In this case it was not my problem but indeed _(ā€˜ā€™) is not very clear. Thanks

1 Like