简体   繁体   中英

Django pass template variable to custom templatetag

I'd like to display django my error messages inside the form as a placeholder, instead of above the form input box itself. Is this possible in Django, or would I have to achieve this by writing some Javascript?

    <div class="form-group">

        {% if login_form.password.errors %}
            {% for error in login_form.password.errors %}
                <p>{{ error }}</p>
            {% endfor %}
        {% endif %}

        <div class="input-group">
            <span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
            {{ login_form.password | placeholder:"password" | addClass:"form-control" }}
        </div>

    </div>

Specific lines of interest. I'd like to change this:

{{ login_form.password | placeholder:"password" | addClass:"form-control" }}

To this

{{ login_form.password | placeholder:{{ error }} | addClass:"form-control" }}

where {{error}} is an the Django error message thrown by the form

I'm thinking there must be some way of getting the string value of a template variable, but can't find any answers

EDIT: I've tried the following, to no avail

<div class="form-group">
    {% if login_form.password.errors %}
        {% for error in login_form.password.errors %}
            <div class="input-group">
                <span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
                {{ login_form.password | placeholder:{{ error|escape }} | addClass:"form-control" }}
            </div>
        {% endfor %}
    {% endif %}
</div>

My custom templatetag looks as follows

@register.filter(name='placeholder')
def placeholder(value, token):
    value.field.widget.attrs["placeholder"] = token
    return value

Django throws a TemplateSyntax Error complaining that:

placeholder requires 2 arguments, 1 provided

First, the nested expression in django template system is incorrect, so placeholder 's filter argument shouldn't be enclosed in double brackets, but written directly:

{{ login_form.password | placeholder:error | addClass:"form-control" }}

Here, error variable is correctly evaluated in context of outer curly brackets scope.

Second, I'd suggest make sure about filter argument's type. If you do expect string value, you may use built-in filter to make an explicit conversion:

{% with err_msg=error|stringformat:"s" %}
{{ login_form.password | placeholder:err_msg | addClass:"form-control" }}
{% endwith %}

This can be done.

{{ login_form.password.errors }}

Here's the relevant documentation for that https://docs.djangoproject.com/en/1.9/topics/forms/#rendering-form-error-messages

The piece of code should be re-written as

{{ login_form.password | placeholder:"password" | addClass:"form-control" }}
{% if login_form.password.errors %}
   <span class="error">{{ login_form.password.errors }}</span>
{% endif %}

or can be done in this way too

{{ login_form.password | placeholder:"password" | addClass:"form-control" }}
<input type="password" class="form-control" placeholder="
{% if login_form.password.errors %}
   {{ login_form.password.errors }}
{% else %}
   password
{% endif %}
">

I have not tested yet, but this may work:

# forms.py
class MyForm(forms.Form):
    class meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        error_messages = self.fields['myfield'].error_messages
        self.fields['myfield'].widget.attrs.update({'placeholder': error_messages})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM