使用auth.user clean方法创建django用户创建表单

时间:2017-05-16 12:22:14

标签: python django forms validation

我创建了一个表单,用于在front-end中添加用户,但form没有验证重复username。我正在使用auth.user模型。

这是我的代码:

views.py

from django.contrib.auth.models import User, Group    
@login_required(login_url='/login/')
    @permission_required('auth.add_user',raise_exception=True)
    def user_new(request):
        if request.method == "POST":

            form = NewUserForm(request.POST)

            if form.is_valid():
                user = form.save(commit=False)
                user.set_password(user.password)
                user.save()
                return redirect('userdetail', user.id)
        else:
            form = NewUserForm()
            return render(request, 'ace/user_edit.html', {'form': form}) 

forms.py

class NewUserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username','first_name','last_name','password','email','is_active','is_staff','groups']
        widgets = {
        'username':TextInput(attrs={'class': u'form-control'}),
        'first_name':TextInput(attrs={'class': u'form-control'}),
        'last_name':TextInput(attrs={'class': u'form-control'}),
        'password':PasswordInput(attrs={'class': u'form-control'}),
        'email':EmailInput(attrs={'class': u'form-control'}),          
        'is_active':NullBooleanSelect(attrs={'class': u'form-control'}), 
        'is_staff':NullBooleanSelect(attrs={'class': u'form-control'}), 
        'groups':SelectMultiple(attrs={'class': u'form-control'}), 
        }  


    def clean_username(self):
        username = self.cleaned_data['username']
        user_exists = User.objects.get(username=username)
        if user_exists:
            raise ValidationError("User exists")

模板

...

{% if form.errors %}

    {% for field in form %}
        {% for error in field.errors %}
            <div class="alert alert-danger">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endfor %}
    {% for error in form.non_field_errors %}
        <div class="alert alert-danger">
            <strong>{{ error|escape }}</strong>
        </div>
    {% endfor %}
{% endif %} 


<form method="POST" class="service-form">{% csrf_token %}

    {{ form.as_p }}
    <button type="submit" class="save btn btn-info">Salvar</button>

    <a href="{% url 'userlist' %}">
            <button class="btn btn-danger" type="button">Cancelar</button>
    </a>                                                   

</form>

...

当我创建新用户时,如果尝试create userusername相同error我得到print

  

视图ace.views.user_new未返回HttpResponse对象。它   返回无。

如果我在print form.errors中添加view行“resource”,我会进入控制台:

  
  • 用户名
  • 用户   存在
  • 4 个答案:

    答案 0 :(得分:1)

    您的视图没有if语句,如果表单无效,则应该使用表单错误呈现模板。

    你需要改变你的观点,

    def user_new(request): 
        if request.method == "POST": 
            form = NewUserForm(request.POST) 
            if form.is_valid(): 
                user = form.save(commit=False)
                user.set_password(user.password)
                user.save() 
                return redirect('userdetail', user.id) 
            else:
                return render(request, 'ace/user_edit.html', {'form': form})
        else: 
            form = NewUserForm() 
            return render(request, 'ace/user_edit.html', {'form': form})
    

    此外,您还需要添加标记{%for field in form%} {{field.error}}{%endfor%}以及表单字段和标签。

    答案 1 :(得分:0)

    当表单无效时,您需要确保视图返回POST请求的响应。您可以通过将最终的return render()语句移出else块来完成此操作。

    def user_new(request):
        if request.method == "POST":
    
            form = NewUserForm(request.POST)
    
            if form.is_valid():
                ...
                return redirect('userdetail', user.id)
        else:
            form = NewUserForm()
        return render(request, 'ace/user_edit.html', {'form': form}) 
    

    答案 2 :(得分:0)

    对于注册django.contrib.auth Userusername字段必须是唯一的。如果您要将其他模型字段用作唯一(作为唯一注册字段)而不是username,例如电子邮件字段,则可以使用this方法或使用其他注册代币,例如{{3} }或django registration

    答案 3 :(得分:0)

    我建议不要在代码中修复错误,而是使用优秀的django-allauth包。它处理用户登录,注销,更改密码,注册和社交登录。我总是通过添加django-allauth启动新项目 - 它会毫不费力地处理所有身份验证问题。

    您可以使用节省的时间和精力编写实际的应用程序代码,而不是解决琐碎的用户管理细节。

    此外,检查模型实例是否存在的正确方法是:

        user_exists = User.objects.filter(username=username).exists()
        if user_exists:
            raise ValidationError("User exists")