• Form组件------注册


    form组件的主要功能如下:

    • 生成页面可用的HTML标签
    • 对用户提交的数据进行校验
    • 保留上次输入内容

    forms.py         form组件一般单独放在一个py文件中,检验错误的信息放在 form_obj.errors

           例如:{ "pwd":["密码太长,"], "email":["格式不对,"] ,   }

    def clean_user(self): 这个叫做局部钩子 也可以引入models.py 进行校验
    from django.shortcuts import render, HttpResponse
    from django.forms import Form, fields
    from django import forms
    from app01 import models
    
    from django.core.validators import RegexValidator
    from django.core.exceptions import ValidationError
    引入
    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三",       # 设置默认值
            error_messages={                 # 重写错误信息。
                "required": "不能为空",
                "invalid": "格式错误",
                "min_length": "用户名最短8位"
                                    },
            validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),
                        RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
                            )
    
        pwd = forms.CharField(
            min_length=6,
            label="密码",
            widget=forms.widgets.PasswordInput(attrs={'class': 'c1'},
            render_value=True, ) # 校验值回不回填到HTML页面中
    
        )
    
        gender = forms.fields.ChoiceField(
            choices=((1, "男"), (2, "女"), (3, "保密")),
            label="性别",
            initial=3,    # 设置默认值
            widget=forms.widgets.RadioSelect  # 设置生成的HTML标签的type类型
        )
    
    
        def clean_username(self):
            username = self.cleaned_data.get("username")
            if "666" in username:
                raise ValidationError("光喊666是学不会!")
            else:
                return username
    
        def __init__(self, *args, **kwargs):
            super(LoginForm, self).__init__(*args, **kwargs)
            self.fields['hobby'].widget.choices = models.Hobby.objects.all().values_list('id', 'name')
    
        # def __init__(self, *args, **kwargs):   #  批量添加样式
        #     super(LoginForm, self).__init__(*args, **kwargs)
        #     for field in iter(self.fields):
        #         self.fields[field].widget.attrs.update({
        #             'class': 'form-control'
        #         })
                
    定义一个Form类
    class RegForm(forms.Form):
    
        user=forms.CharField(max_length=8,label="用户名",
                             widget=widgets.TextInput(attrs={"class":"form-control"})
                             )
        pwd=forms.CharField(min_length=4,label="密码",
                            widget=widgets.PasswordInput(attrs={"class":"form-control"}))
        repeat_pwd=forms.CharField(min_length=4,label="确认密码",
                             widget=widgets.PasswordInput(attrs={"class": "form-control"}))
        email=forms.EmailField(label="邮箱",
                             widget=widgets.EmailInput(attrs={"class": "form-control"})
        )
    
    
        def clean_user(self):
            val=self.cleaned_data.get("user")
            # val=self.cleaned_data.get("pwd")
    
            ret=UserInfo.objects.filter(username=val)
            if not ret:
                return val
            else:
                raise ValidationError("该用户已存在")
    
        def clean(self):
            if self.cleaned_data.get("pwd")==self.cleaned_data.get("repeat_pwd"):
                return self.cleaned_data
            else:
                raise ValidationError("两次密码不一致!")
    局部钩子 全局钩子

    views.py

    views.py     (from app import forms            from .models import UserInfo)
    from app import forms 
    from .models import UserInfo
    引入
    def register2(request):
        form_obj = RegisterForm()
        if request.method == "POST":
            form_obj = RegisterForm(request.POST)  # 把POST请求的数据传到RegisterForm
            if form_obj.is_valid():  # 执行校验规则
                # 校验通过
                # 从校验好的数据中取需要的字段值
                username = form_obj.cleaned_data.get("username")
                pwd = form_obj.cleaned_data.get("pwd")
                # 入库生成一条新纪录
                models.UserInfo.objects.create(usernama=username,pwd=pwd)
                return HttpResponse("注册成功")
        # 实例化一个RegisterForm对象
        return render(request, "register2.html", {"form_obj": form_obj})
    def 函数逻辑

    ps:   models.User.objects.create(**form_obj.cleaned_data) 

      cleaned_data里面没有csrftoken  k  v

    html.html  (3种渲染方式)   ( 1、 {{ form_obj.as_p }}  会render初所有的,不建议使用)

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>login</title>
      <style>
        .error {
          color: red;
        }
      </style>
    </head>
    <body>
    <form action="/login2/" method="post" novalidate>
      {% csrf_token %}
      <p>
        {{ form_obj.username.label }}
        {{ form_obj.username }}
        <span class="error">{{ form_obj.username.errors.0 }}</span>
      </p>
      <p>
        {{ form_obj.pwd.label }}
        {{ form_obj.pwd }}
        <span class="error">{{ form_obj.pwd.errors.0 }}</span>
      </p>
      <p>
        <input type="submit">
        <span class="error">{{ error_msg }}</span>
      </p>
    </form>
    </body>
    </html>
    2、html(csrftoken)

     上边的如果字段很多会麻烦,此时可以使用for循环来生成,但是为了给每个标签添加样式可以使用  widget  =widgets...............   例如:widget  =widgets.PasswordInput.....密码变加密

    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form action="" novalidate >
    {#                form组件#}
                    {% for field in form %}
                        <div class="form-group">
                            <label for="">{{ field.label }}</label>
                            {{ field }} <span class="error pull-right"></span>
                        </div>
                    {% endfor %}
    {#                    图片#}
                    <div class="form-group">
                        <label for="avatar">头像<img class="avatar" src="/static/img/default.png" alt=""></label>
                        <input type="file" id="avatar">
                    </div>
    {#                上传#}
                    <input type="button" class="btn btn-default reg_btn pull-right" value="提交"><span class="error"
                                                                                                     style="color: red;margin-left: 20px"></span>
                </form>
            </div>
        </div>
    </div>
    
    {% csrf_token %}
    3、for循环(form=RegForm()) 

    forms.py其他情况

    select

    class LoginForm(forms.Form):
    
        hobby = forms.fields.ChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
            label="爱好",
            initial=3,
            widget=forms.widgets.Select
        )
    select单选
    class LoginForm(forms.Form):
    
        hobby = forms.fields.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
            label="爱好",
            initial=[1, 3],
            widget=forms.widgets.SelectMultiple
        )
    select多选

    checkbox

    class LoginForm(forms.Form):
        ...
        keep = forms.fields.ChoiceField(
            label="是否记住密码",
            initial="checked",
            widget=forms.widgets.CheckboxInput
        )
    checkbox单选
    class LoginForm(forms.Form):
    
        hobby = forms.fields.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
            label="爱好",
            initial=[1, 3],
            widget=forms.widgets.CheckboxSelectMultiple
        )
    checkbox多选
    gender=forms.ChoiceField(choices=((1,""),(2,""),(3,"其他")))
    publish=forms.ChoiceField(choices=Publish.objects.all().values_list("pk","title"))
    publish=forms.ModelChoiceField(queryset=Publish.objects.all())
    authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())

    爷类:chicefield                                                

    父类:modelchoicefield   单选的select

    子类:multiolechoicefield  多选的select

    关于choice的注意事项:

    在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。

    from django.forms import Form
    from django.forms import widgets
    from django.forms import fields
    
     
    class MyForm(Form):
     
        user = fields.ChoiceField(
            # choices=((1, '上海'), (2, '北京'),),
            initial=2,
            widget=widgets.Select
        )
     
        def __init__(self, *args, **kwargs):
            super(MyForm,self).__init__(*args, **kwargs)
            # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)
            #
            self.fields['user'].widget.choices = models.Classes.objects.all().values_list('id','caption')
    choice实例化对象init

    init还可以批量添加样式

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三",
            error_messages={
                "required": "不能为空",
                "invalid": "格式错误",
                "min_length": "用户名最短8位"
            }
        ...
    
        def __init__(self, *args, **kwargs):
            super(LoginForm, self).__init__(*args, **kwargs)
            for field in iter(self.fields):
                self.fields[field].widget.attrs.update({
                    'class': 'form-control'
                })
    init批量添加样式
  • 相关阅读:
    生产者消费者模式 (在已有线程下不断生产不断消费)
    Spring boot Spring cloud 框架搭建
    个人见解
    加入博客园!
    sqlserver 工具
    slqserver 拆分函数
    sqlserver 自定义函数与存储过程的区别
    sqlserver row_number() over() 理解
    C# Newtonsoft.Json JObject移除属性
    PropertyInfo 简单用法
  • 原文地址:https://www.cnblogs.com/nick477931661/p/8760636.html
Copyright © 2020-2023  润新知