• Python全栈之路-Django(十四)


    1 Form表单验证内部原理

    def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    else:
        obj = LoginForm(request.POST)
        # is_valid
        """
        1. LoginForm实例化时,
            self.fields={
                'user': 正则表达式
                'pwd': 正则表达式
            }
        2. 循环self.fields
                flag = True
                errors
                cleaned_data
                for k,v in self.fields.items():
                # 1. user,正则表达式
                input_value = request.POST.get(k)
                正则表达式和input_value
                flag = False
                return flag
        """
        if obj.is_valid():
            print(obj.cleaned_data)
        else:
            print(obj.errors)
        return render(request,'login.html')
    

    2 Form组件 Ajax提交

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^ajax_login/', views.ajax_login),
        url(r'^test/', views.test),
    ]
    

    views.py

    def ajax_login(request):
        ret = {'status': True, 'msg': None}
        obj = LoginForm(request.POST)
        if obj.is_valid():
            print(obj.cleaned_data)
            return HttpResponse(json.dumps(ret))
        else:
            print(obj.errors)
            ret['status'] = False
            ret['msg'] = obj.errors
            return HttpResponse(json.dumps(ret))
    

    templates.login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>用户登录</h1>
        <form id="f1" action="/login/" method="post">
            {% csrf_token %}
            <p><input type="text" name="user">{{ obj.errors.user.0 }}</p>
            <p><input type="password" name="pwd">{{ obj.errors.pwd.0 }}</p>
            <p><input type="submit" value="提交"></p>
            <p><input type="button" value="Ajax提交" onclick="ajaxSubmit();"></p>
        </form>
        <script src="/static/jquery-3.2.1.min.js"></script>
        <script>
            function ajaxSubmit() {
                $('.c1').remove();
                $.ajax({
                url: '/ajax_login/',
                type: 'POST',
                data: $('#f1').serialize(),
                dataType: "JSON",
                success:function (arg) {
                    console.log(arg);
                    if (arg.status){
    
                    }else{
                        console.log(arg.msg);
                        $.each(arg.msg, function (index,value) {
                            var tag = document.createElement('span');
                            tag.innerText = value[0];
                            tag.className = 'c1';
                            $('#f1').find('input[name="'+index+'"]').after(tag);
                        })
    
                    }
                }
            })
            }
    
        </script>
    </body>
    </html>
    

    3 Form组件常用字段和参数

    3.1 Form组件常用字段

    class TestForm(Form):
        t1 = fields.CharField(
            required=True,
            max_length=8,
            min_length=2,
            error_messages={
                'required': 't1不能为空',
                'max_length': 't1太长',
                'min_length': 't1太短',
            }
        )
        t2 = fields.IntegerField(
            max_value=10,
            min_value=1000,
            error_messages={
                'min_value': '必须大于10',
                'max_value': '必须小于1000',
                'required': 't2不能为空',
                'invalid': 't2必须是数字'
            }
        )
        t3 = fields.EmailField(
            error_messages={
                'required': 't3不能为空',
                'invalid': 't3必须是邮箱'
            }
        )
        t4 = fields.URLField()
        t5 = fields.SlugField()  # 字符串只能包含数字、字母、下划线等字符
        t6 = fields.GenericIPAddressField()
        t7 = fields.DateField()
        t8 = fields.DateTimeField()
        t9 = fields.RegexField(
            '139d+',
            error_messages={
                'invalid': '输入一个有效的值'
            }
        )  # 自定义正则表达式 包含:1 是否为空 2 最长 3 最短 4 自定义规则
    

    3.1 Form组件常用参数

    class TestForm(Form):
        t1 = fields.CharField(
            required=True,
    
            # 用于生成HTML标签并保留用户上次输入的数据  只推荐使用widget
            widget=widgets.Textarea,                      # 自动生成HTML标签
            label='用户名',                # 前端可以通过obj.t1.label访问
            initial='root',            # 在input框中显示默认值
            help_text='请输入用户名...',       # 提供帮助信息
            label_suffix=':',   # Label内容后缀
            # validators=[],                    # 自定义正则表达式
            disabled=True,                    # 是否可编辑
    
            max_length=8,
            min_length=2,
            error_messages={
                'required': 't1不能为空',
                'max_length': 't1太长',
                'min_length': 't1太短',
            }
        )
    

    4 Form组件保留上次输入数据示例

    app01.views.py

    class RegisterForm(Form):
        user = fields.CharField(min_length=8)
        email = fields.EmailField()
        password = fields.CharField(min_length=8, max_length=16)
        phone = fields.RegexField('139d+')
    
    def register(request):
        if request.method == 'GET':
            obj = RegisterForm()
            return render(request, 'register.html', {'obj': obj})
        else:
            obj = RegisterForm(request.POST)
            if obj.is_valid():
                print(obj.cleaned_data)
            else:
                print(obj.errors)
            return render(request, 'register.html', {'obj': obj})
    

    templates.register.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/register/" method="post" novalidate>
        {% csrf_token %}
        <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>
        <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
        <p>{{ obj.password }}{{ obj.errors.password.0 }}</p>
        <p>{{ obj.phone }}{{ obj.errors.phone.0 }}</p>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>
    

    5 利用Form组件实现班级管理和学生管理

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^classes/', views.classes),
    
        url(r'^add_class/', views.add_class),
        url(r'^edit_class/(d+)/', views.edit_class),
        url(r'^students/', views.students),
        url(r'^add_student/', views.add_student),
        url(r'^edit_student/(d+)/', views.edit_student),
    ]
    

    app01.models.py

    from django.db import models
    
    # Create your models here.
    
    
    class Classes(models.Model):
        title = models.CharField(max_length=32)
    
    
    class Student(models.Model):
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        age = models.IntegerField()
        cls_id = models.ForeignKey('Classes')
    
    
    class Teacher(models.Model):
        tname = models.CharField(max_length=32)
        c2t = models.ManyToManyField('Classes')
    

    app01.views.py

    from django.shortcuts import render, redirect
    from app01 import models
    # Create your views here.
    from django.forms import Form, fields
    from django.forms import widgets
    
    
    class ClassForm(Form):
        title = fields.RegexField(
            '全栈d+期',
            error_messages={
                'required': '不能为空',
                'invalid': '格式错误'
            }
        )
    
    def classes(request):
        if request.method == 'GET':
            class_list = models.Classes.objects.all()
            return render(request, 'classes.html', {'class_list': class_list, })
    
    
    def add_class(request):
        if request.method == 'GET':
            obj = ClassForm()
            return render(request, 'add_class.html', {'obj': obj})
        else:
            obj = ClassForm(request.POST)
            if obj.is_valid():
                models.Classes.objects.create(**obj.cleaned_data)
                return redirect('/classes/')
            else:
                print(obj.errors)
                return render(request, 'add_class.html', {'obj': obj})
    
    
    def edit_class(request, nid):
        if request.method == 'GET':
            row = models.Classes.objects.filter(id=nid).first()
            # 下面是两种让页面显示初始值的方法
            # obj = ClassForm(data={'title': row.title})  # 会对默认值进行校验
            obj = ClassForm(initial={'title': row.title})  # 不会对默认值进行校验
    
            return render(request, 'edit_class.html', {'nid': nid, 'obj': obj})
        else:
            obj = ClassForm(request.POST)
            if obj.is_valid():
                print(obj.cleaned_data)
                models.Classes.objects.filter(id=nid).update(**obj.cleaned_data)
                return redirect('/classes/')
            print(obj.errors)
            return render(request, 'edit_class.html', {'nid':nid, 'obj': obj})
    
    
    class StudentForm(Form):
        name = fields.CharField(
            max_length=10,
            min_length=2,
            widget=widgets.TextInput(attrs={'class': 'form-control'})
        )
        email = fields.EmailField(
            widget=widgets.TextInput(attrs={'class': 'form-control'}),
        )
        age = fields.IntegerField(
            min_value=20,
            max_value=30,
            widget=widgets.TextInput(attrs={'class': 'form-control'})
        )
        cls_id_id = fields.IntegerField(
            # widget=widgets.Select(choices=[(1,'上海'), (2,'北京')]),
            widget=widgets.Select(
                choices=models.Classes.objects.all().values_list('id', 'title'),
                attrs={'class': 'form-control'}
            )
        )
    
    
    def students(request):
        stu_list = models.Student.objects.all().values('id', 'name', 'age', 'email', 'cls_id__title')
        return render(request, 'students.html', {'stu_list': stu_list})
    
    def add_student(request):
        if request.method == 'GET':
            obj = StudentForm()
            return render(request, 'add_student.html', {'obj': obj})
        else:
            obj = StudentForm(request.POST)
            if obj.is_valid():
                print(obj.cleaned_data)
                models.Student.objects.create(**obj.cleaned_data)
                return redirect('/students/')
            else:
                print(obj.errors)
                return render(request, 'add_student.html', {'obj': obj})
    
    def edit_student(request, nid):
        if request.method == 'GET':
            row = models.Student.objects.filter(id=nid).values().first()
            obj = StudentForm(row)
            return render(request, 'edit_student.html', {'nid': nid, 'obj': obj})
        else:
            obj = StudentForm(request.POST)
            if obj.is_valid():
                models.Student.objects.filter(id=nid).update(**obj.cleaned_data)
                return redirect('/students/')
            else:
                print(obj.errors)
                return render(request, 'edit_student.html', {'nid': nid, 'obj': obj})
    

    templates.classes.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>班级列表</h1>
        <div>
            <a href="/add_class/">添加</a>
        </div>
    <ul>
        {% for row in class_list %}
            <li>{{ row.id }} {{ row.title }} <a href="/edit_class/{{ row.id }}/">编辑</a></li>
        {% endfor %}
    
    </ul>
    </body>
    </html>
    

    templates.add_class.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>添加班级</h1>
        <form action="/add_class/" method="post" novalidate>
            {% csrf_token %}
            <p>{{ obj.title }}{{ obj.errors.title.0 }}</p>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    

    templates.edit_class.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>编辑班级</h1>
        <form action="/edit_class/{{ nid }}/" method="post">
            {% csrf_token %}
            <p>{{ obj.title }}{{ obj.errors.title.0 }}</p>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    

    templates.students.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>学生列表</h1>
        <a href="/add_student/">添加</a>
        <ul>
            {% for stu in stu_list %}
                <li>{{ stu.id }}-{{ stu.name }}-{{ stu.age }}-{{ stu.email }}-{{ stu.cls_id__title }} <a href="/edit_student/{{ stu.id }}/">编辑</a></li>
            {% endfor %}
    
        </ul>
    
    </body>
    </html>
    

    templates.add_student.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>添加学生</h1>
        <form action="/add_student/" method="post" novalidate>
            {% csrf_token %}
            <p>{{ obj.name }}</p>
            <p>{{ obj.email }}</p>
            <p>{{ obj.age }}</p>
            <p>{{ obj.cls_id_id }}</p>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    

    templates.edit_student.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"></link>
    </head>
    <body>
    
    
        <div style=" 500px;margin: 10px auto;">
            <form class="form-horizontal" action="/edit_student/{{ nid }}/" method="post" novalidate>
                {% csrf_token %}
              <div class="form-group">
                <label class="col-sm-2 control-label">姓名</label>
                <div class="col-sm-10">
                    {{ obj.name }}
                </div>
              </div>
              <div class="form-group">
                <label class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-10">
                    {{ obj.email }}
                </div>
              </div>
                <div class="form-group">
                <label class="col-sm-2 control-label">年龄</label>
                <div class="col-sm-10">
                    {{ obj.age }}
                </div>
              </div>
                <div class="form-group">
                <label class="col-sm-2 control-label">班级</label>
                <div class="col-sm-10">
                    {{ obj.cls_id_id }}
                </div>
              </div>
              <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                  <button type="submit" class="btn btn-default">Submit</button>
                </div>
              </div>
            </form>
        </div>
    </body>
    </html>
    
  • 相关阅读:
    使用virtualenv搭建python3的环境
    Linux/unix inode
    转:进程间通信方式
    保研复试上机——数据库
    转:mysql grant
    mysql 查询结果创建表
    279. Perfect Squares
    Mybatis中javaType和jdbcType对应和CRUD例子
    mysql explain
    91. Decode Ways
  • 原文地址:https://www.cnblogs.com/wanyuetian/p/7138768.html
Copyright © 2020-2023  润新知