问题
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