Django 'str' object has no attribute 'as_widget'

拈花ヽ惹草 提交于 2019-12-12 04:58:32

问题


I've made a register form in django and i've created a template tag add_class to create users, the problem is i'm getting this error:

'str' object has no attribute 'as_widget'

to

{{ form.username|add_class:'form-control' }}

register_user.html

<form class="form-horizontal" method="POST" action="">
    {% csrf_token %}
    {% if form.errors %}
        <p>Your username and password didn't match. Please try again.</p>
    {% endif %}
    <div class="form-group">
        <div class="col-md-12">
            {{ form.username|add_class:'form-control' }}
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            {{ form.email|add_class:'form-control' }}
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            {{ form.password|add_class:'form-control' }}
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            {{ form.confirm_password|add_class:'form-control' }}
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-12">
            <button type="submit" class="btn btn-info btn-block">Register</button>
            <input type="hidden" name="next" value="{% url 'register_user_success' %}"/>
        </div>
    </div>
</form>

form.py

class UserForm(ModelForm):
    username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
    email = forms.EmailField(widget=forms.EmailInput(attrs={'placeholder': 'E-mail'}))
    confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password'}))

    class Meta:
        model = CustomUser
        fields = ('username', 'email', 'password', 'confirm_password')

    def clean(self):
        cleaned_data = super(UserForm, self).clean()
        password = cleaned_data.get('password')
        confirm_password = cleaned_data.get('confirm_password')
        if password != confirm_password:
            raise forms.ValidationError('Password did not match.')

template tag: my_filters.py

from django import template

register = template.Library()


@register.filter(name='add_class')
def add_class(value, arg):
    return value.as_widget(attrs={'class': arg})

I've made the template tag so i can add classes from css.

views.py

def register_user(request):
    data = dict()
    if request.method == 'POST':
        form = UserForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.set_password(user.password)
            user.save()
            return redirect('/register_user/success/')
    else:
        data['form'] = UserForm()
    return render(request, 'register_user.html', data)

回答1:


If your form is not valid, you re-render the template but you do not add the form to the context. So, when the template comes to render {{ form.username }} or whatever, it does not find it - and the default when a variable is not found is to use an empty string. So, it is the empty string that gets passed to the filter, hence the error you see.

The solution is to ensure you always pass the form into the template:

else:
    form = UserForm()
return render(request, 'register_user.html', {'form': form})


来源:https://stackoverflow.com/questions/43895198/django-str-object-has-no-attribute-as-widget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!