Django之ModelForm用户登录注册

1. urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^register/', views.register),
]

2.model.py

class User(models.Model):
    username = models.CharField(max_length=32)
    email = models.EmailField()
    pwd = models.CharField(max_length=12)

3.Vies.py

def register(request):
    # 只有当请求为 POST 时,才表示用户提交了注册信息
    if request.method=='POST':
        # request.POST 是一个类字典数据结构,记录了用户提交的注册信息
        # 这里提交的就是用户名(username)、密码(password)、邮箱(email)
        # 用这些数据实例化一个用户注册表单
        obj = forms.RegisterForm(request.POST)
        if obj.is_valid():
            # 验证数据的合法性
            username = obj.cleaned_data.get('username')
            password = obj.cleaned_data.get('pwd')
            email = obj.cleaned_data.get('email')
            models.User.objects.create(username=username,pwd=password,email=email)
            # 注册成功,跳转XXX页
            return HttpResponse('register success')
        else:
            print(obj.errors)
    else:
        # 请求不是 POST,表明用户正在访问注册页面,展示一个空的注册表单给用户
        obj = forms.RegisterForm()
        # 渲染模板
        # 如果用户正在访问注册页面,则渲染的是一个空的注册表单
        # 如果用户通过表单提交注册信息,但是数据验证不合法,则渲染的是一个带有错误信息的表单
    return render(request,'register.html',{'form':obj})
Register
def register(request):
    if request.method=='POST':
        obj = forms.RegisterForm(request.POST)
        if obj.is_valid():
            username = obj.cleaned_data.get('username')
            password = obj.cleaned_data.get('pwd')
            email = obj.cleaned_data.get('email')
            models.User.objects.create(username=username,pwd=password,email=email)
            return HttpResponse('register success')
        else:
            print(obj.errors)
    else:
        obj = forms.RegisterForm()
    return render(request,'register.html',{'form':
def login(request):
    if request.method=='POST':
        obj = forms.loginForm(request.POST)
        if obj.is_valid():
            username = obj.cleaned_data['username']
            password = obj.cleaned_data['pwd']
            namefilter = models.User.objects.filter(username=username,pwd=password)
            if namefilter:
                return HttpResponse('OK')
        else:
            print(obj.errors.as_data())
    else:
        obj = forms.loginForm()
    return render(request,'login.html',{'form':obj})
login

4.forms.py

from django import forms
from django.forms import fields,widgets
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError


class RegisterForm(forms.Form):

    username = fields.CharField(
        required=True,
        widget=widgets.TextInput(attrs={'placeholder': '用户名为8-12个字符'}),
        min_length=6,
        max_length=12,
        strip=True,
        error_messages={
            'required':'标题不能为空',
            'min_length':'用户名最少为6个字符',
            'max_length':'用户名最不超过为20个字符'
        }
    )

    email = fields.EmailField(
        required=True,
        widget=widgets.TextInput(attrs={'placeholder': '请输入邮箱'}),
        # strip=True,
        error_messages={'required': '邮箱不能为空',
                        'invalid':'请输入正确的邮箱格式'}
    )

    pwd = fields.CharField(
        required=True,
        widget=widgets.PasswordInput(attrs={'placeholder': '请输入密码,必须包含数字,字母,特殊字符'}),
        min_length=6,
        max_length=12,
        # strip=True,
        # validators=[
        #     RegexValidator(r'((?=.*d))^.{6,12}$', '必须包含数字'),
        #     RegexValidator(r'((?=.*[a-zA-Z]))^.{6,12}$', '必须包含字母'),
        #     RegexValidator(r'((?=.*[^a-zA-Z0-9]))^.{6,12}$', '必须包含特殊字符'),
        #     RegexValidator(r'^.(S){6,10}$', '密码不能包含空白字符'),
        # ],
        error_messages={
            'required':'密码不能为空',
            'min_length':'密码最少6个字符',
            'max_length':'密码不超过12个字符'
        }
    )

    pwd_again = fields.CharField(
        widget=widgets.PasswordInput(attrs={ 'placeholder': '请再次输入密码!'}),
        required=True,
        error_messages={'required': '请再次输入密码!!!!'}
    )

    def clean_username(self):
        username = self.cleaned_data.get('username')
        users = models.User.objects.filter(username=username).count()
        if users:
            raise ValidationError('用户已经存在!')
        return username

    def clean_email(self):
        email = self.cleaned_data.get('email')
        email_count = models.User.objects.filter(email=email).count()
        if email_count:
            raise forms.ValidationError('邮箱已经存在!')
        return email

    def clean(self):
        # cleaned_data = super(RegisterForm,self).clean()
        password1 = self.cleaned_data.get('pwd')
        password2 = self.cleaned_data.get('pwd_again')
        if password1 and password2 and password1 != password2:
            # raise forms.ValidationError('两次输入密码不一致')
            self.add_error('pwd_again','两次输入密码不一致')
            return None
        else:
            return self.cleaned_data

    # def _clean_new_password2(self):
    #     password1 = self.cleaned_data.get('pwd')
    #     password2 = self.cleaned_data.get('pwd_again')
    #     if password1 != password2:
    #         raise ValidationError('两次输入密码不一致')
    #
    # def clean(self):
    #     self._clean_new_password2()
Register
class loginForm(forms.Form):
    username = fields.CharField(
        required=True,
        widget=widgets.TextInput(attrs={'placeholder': '请输入用户名'}),
        min_length=6,
        max_length=12,
        error_messages={'required':'用户名不能为空'}
    )
    pwd = fields.CharField(
        widget=widgets.PasswordInput(attrs={'placeholder': '请输入密码'}),
        required=True,
        min_length=6,
        max_length=12,
        error_messages={'required':'密码不能为空'}
    )

    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('pwd')
        c = models.User.objects.filter(username=username,pwd=password)
        if c:
            return self.cleaned_data
        else:
            self.add_error('pwd','用户名或密码不一致')
            return None

    # def clean_username(self):
    #     username = self.cleaned_data.get('username')
    #     email_count = models.User.objects.filter(username=username).count()
    #     if not email_count:
    #         raise ValidationError('用户名不存在!')
    #     return username
    #
    # def clean_pwd(self):
    #     password = self.cleaned_data.get('pwd')
    #     email_count = models.User.objects.filter(pwd=password).count()
    #     if not email_count:
    #         raise ValidationError('密码错误!')
login

5.HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/register/" method="post">
        {% csrf_token %}
        <p>
        <label>用户名:</label>
        {{ form.username }}<span style="color: red">{{ form.errors.username }}</span>
        </p>
        <p>
        <label>密码:</label>
        {{ form.pwd }}<span style="color: red">{{ form.errors.pwd }}</span>
        </p>
        <p>
        <label>再次输入密码:</label>
        {{ form.pwd_again }}<span style="color: red">{{ form.errors.pwd_again }}</span>
        </p>
        <p>
        <label>邮箱:</label>
        {{ form.email }}<span style="color: red">{{ form.errors.email }}</span>
        </p>
        <input type="submit" value="提交"></input>

    </form>
</body>
</html>
register
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post" action="/login/">
        {% csrf_token %}
        <label for="username">用户名</label>{{ form.username }}
        <label for="password">密码</label>
        {{ form.pwd }}<span style="color: red">{{ form.errors.pwd }}</span>
         <input type="submit" value="提交"></input>
    </form>
</body>
</html>
login

6.form验证某个字段 self.clean_字段名

     def clean_username(self):
        username = self.cleaned_data.get('username')
        users = models.User.objects.filter(username=username).count()
        if users:
            raise ValidationError('用户已经存在!')
        return username
        # self.errors = {'code': ['用户已经存在!'], 'xx':[错误1,错误2]}

form验证多个字段 self.clean

    def clean(self):
        #此时,已经拿到所有的input值,对两次输入密码进行验证
        # cleaned_data = super(RegisterForm,self).clean()
        password1 = self.cleaned_data.get('pwd')
        password2 = self.cleaned_data.get('pwd_again')
        if password1 and password2 and password1 != password2:
             raise forms.ValidationError('两次输入密码不一致')# 默认放到self.errors['__all__']里面
        else:
            return self.cleaned_data
“”“
self.errors = {'__all__': ['两次输入密码不一致'], 'xx':[错误1,错误2]}
 NON_FIELD_ERRORS = '__all__'   前台获取需要用到
 此时前端获取该错误; obj.non_field_errors
”“”

form验证多个字段 self.clean 指明错误信息的Key,方便前端使用

    def clean(self):
        # cleaned_data = super(RegisterForm,self).clean()
        password1 = self.cleaned_data.get('pwd')
        password2 = self.cleaned_data.get('pwd_again')
        if password1 and password2 and password1 != password2:
            self.add_error('pwd_again','两次输入密码不一致')
                # 此时不用抛出异常了,因为抛出异常
            # 抛出异常也是执行self.add_error
            return None
        else:
            return self.cleaned_data

此时在前端显示该错误: obj.errors.pwd_again

form 的错误信息self.errors

# form标签数据验证错误信息
    self.errors = {'username':[错误1, 错误2], 'password': [错误1, 错误2]}
    def clean_xx(self) 如果遇到错,放到self.errors['xx']里面
    def clean(self) 如果遇到错,放到self.errors['__all__']里面

    但是如果要前端获取self.errors['__all__']错误,obj.errors.__all__是拿不到的
    而是obj.non_field_errors, 不是self.errors.non_fields_errors

7.效果

原文地址:https://www.cnblogs.com/zhangzihong/p/8568619.html