【问题标题】:error from template tags: 'str' object has no attribute 'as_widget'来自模板标签的错误:“str”对象没有属性“as_widget”
【发布时间】:2019-04-27 17:27:59
【问题描述】:

我制作了一个模板标签,当我在我的模板中使用它时,我收到了这个错误:

'str' 对象没有属性'as_widget'

这是我的模板标签的代码:

from django import template
register = template.Library()
@register.filter
def field_type(bound_field):
    return bound_field.field.widget.__class__.__name__


@register.filter
def input_class(bound_field):
    css_class = ''
    if bound_field.form.is_bound:
        if bound_field.errors:
            css_class = 'is-invalid'
        elif field_type(bound_field) != 'PasswordInput':
            css_class = 'is-valid'
    return 'form-control {}'.format(css_class)

我的模板在这里:

{% extends 'board/account.html' %}
{% load widget_tweaks %}
{% load form_tags %}
{% block title %}Sign up{% endblock title %}

{% block content %}
<div class="accountform">
    <form method="POST">
        <h4 class="display-6 text-white p-3">Create your account</h4>
        {% csrf_token %}

        <div class="alert alert-danger p-0" style="border:none;">
            {% for field in form.visible_fields %}
            {% for error in field.errors %}
            <span class="err">{{ error }}</span><br>
            {% endfor %}
            {% endfor %}
        </div>

        <div class="form-group">
            <label for="id_username">Username</label>
            {% render_field form.username|input_class class='form-control' placeholder='John Doe' %}
        </div>

        <div class="form-group">
            <label for="id_email">Email</label>
            {% render_field form.email|input_class class='form-control' placeholder='johndoe@email.com' %}
        </div>

        <div class="row">
            <div class="form-group col-md-6">
                <label for="id_password1">Password</label>
                {% render_field form.password1|input_class class='form-control' placeholder='****' %}
            </div>
            <div class="form-group col-md-6">
                <label for="id_password2">Confirm Password</label>
                {% render_field form.password2|input_class class='form-control' placeholder='****' %}
            </div>
        </div>

        <input type="submit" value="Sign up" class="btn btn-primary btn-block">
        <p class="display-6 bg-signup p-3">Have an account <a href="{% url 'signin' %}">Sign In</a></p>
    </form>
</div>

</div>
{% endblock content %}

我在 SO 中看到了类似的问题和批准的答案,基本上说这个问题的解决方案是在上下文中添加表单,嗯,已经添加了,这里是视图

def signup_view(request):
    if request.method == 'POST':
        form = UserRegistrationForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return redirect('board:home')
    form = UserRegistrationForm(request.POST)
    return render(request, 'accounts/signup.html', {'form': form})

请帮我解决这个问题。感谢您的帮助。

【问题讨论】:

  • 但是您的input_class 过滤器采用绑定字段并返回一个字符串,然后您将其传递给render_field,它需要一个实际字段。你为什么做这个? input_class 有什么意义?
  • 如果绑定字段有错误我想添加from-control is_invalid CSS 类,但如果绑定字段没有错误我想添加form-control is_valid CSS 类。
  • 但是您仍然需要将实际字段传递给render_field
  • 对不起先生,我刚开始学习这些模板标签。
  • 我不明白你上一条评论的意思,如果你能详细说明一下(Django 初学者)

标签: python django templatetags


【解决方案1】:

这些模板标签似乎没有任何理由。 django-widget-tweaks 已经具备add a custom error class with render_field 的能力,并且您已经知道何时渲染密码字段,以便在需要时添加该类。

(另外,django-widget-tweaks 已经提供了field_type filter)。

所以:

{% with WIDGET_ERROR_CLASS='my_error' %}
    <div class="form-group">
        <label for="id_username">Username</label>
        {% render_field form.username class+='form-control' placeholder='John Doe' %}
    </div>

    <div class="form-group">
        <label for="id_email">Email</label>
        {% render_field form.email class+='form-control' placeholder='johndoe@email.com' %}
    </div>

    <div class="row">
        <div class="form-group col-md-6">
            <label for="id_password1">Password</label>
            {% render_field form.password1| class+='form-control' placeholder='****' %}
        </div>

    ...

{% endwith %}

【讨论】:

    【解决方案2】:

    你做错了,你必须在类属性中添加calss 而不是将类名呈现为字段。这样做。

    {% render_field form.username class=form.username|input_class placeholder='John Doe' %}
    

    【讨论】:

    • 为什么我要再次添加额外的add:form.username
    • 因为 1)您必须将 form.username 传递给 input_class 作为参数 2)您正在使用 form-control 类,您还必须将动态类与它连接起来。 add 会做到的。所以表达式'form-control '|add:form.username|input_class 的结果将是form-control form-control &lt;css_class&gt;。我认为你应该省略 add 因为你也从模板标签返回 from-control 。查看我的编辑。
    • 我之前试过这个解决方案;我想它会添加这些类,但它不会向这些输入元素添加任何类。它所做的只是消除该错误。
    • 那么错误一定在其他地方。我建议你使用 pycharm 或类似的东西来调试你的代码,并仔细遵循第三方包的文档。
    猜你喜欢
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2021-07-19
    • 1970-01-01
    • 2018-07-24
    • 2018-02-08
    • 2018-03-15
    相关资源
    最近更新 更多