zoukankan      html  css  js  c++  java
  • Python学习---Form拾遗180322

    image

    Form操作之错误信息操作

    1. 用户发送请求过来

    2. for 循环对字段进行正则表达式的验证  fields.clean(value)

    3. 自定义clean_字段() 进行名字段值正确性的校验

    4. 自定义clean()的内容校验,会进行异常信息的捕捉

    5. post_clean()方法的校验,不允许抛出异常,self.add_error(进行校验)

    注意  self.add_error(None, ValidatorError(‘’))   这里虽然写的是None,但实际上会转换为__all__

            Django内部会进行转换的:self.add_error(‘__all__’, ValidatorError(‘’))

    settings.py

    INSTALLED_APPS = [
       ...
     'app01',   # 注册app
    ]
    STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)  # 现添加的配置,这里是元组,注意逗号
    TEMPLATES = [
       ...
       'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ]

    urls.py

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url, include
    from app01 import views
    urlpatterns = [
       url('fm/', views.fm),
    ]

    views.py

    from django.shortcuts import render, redirect, HttpResponse
    from app01 import models,fields
    class Fm(forms.Form):
        username = fields.CharField(max_length=32, label='用户名')
        email = fields.EmailField(label='邮箱')
    
        # 这里是对username字段的内容进行验证的
        def _clean_username(self):
            data = self.cleaned_data['username']
            if (data == 'root'):
                return data    # 验证通过,返回一个结果给forms.py中full_clean()方法的调用处
            else:
                from django.core.exceptions import  ValidationError
                # 这里的异常也是forms.py中full_clean()的异常捕获
                raise ValidationError("请使用root用户登录...")
    
        # 这里实际上是调用 _clean_form(self)里的clean()进行错误拓展
        def clean(self):
            data = self.cleaned_data['username']
            email = self.cleaned_data['email']
            if (data == 'root' and email == 'root@live.com'):
                pass  # 因为父级别的_post_clean也是什么都不操作
            else:
                from django.core.exceptions import ValidationError
                # 这里的异常是forms._clean_form()的异常捕获
                raise ValidationError("用户名或email错误...")
            return self.cleaned_data
    
        # _post_clean和_clean_form里面的clean()效果同,所以这里隐去
        # 这里是个_post_clean里面的Hook,里面的方法体为空
        # def _post_clean(self):
        #     data = self.cleaned_data['username']
        #     email = self.cleaned_data['email']
        #     if (data == 'root' and email == 'root@live.com'):
        #         pass    # 因为父级别的_post_clean也是什么都不操作
        #     else:
        #         from django.core.exceptions import ValidationError
        #         # 这里的异常是forms._clean_form()的异常捕获
        #         raise ValidationError("用户名或email错误...")
    
    def fm(request):
        if request.method == "GET":
            obj = Fm()
            return render(request, 'fm.html', {"obj": obj})
        else:
            obj = Fm(request.POST)
            obj.is_valid()
            # data = obj.clean()   因为Fm()里面覆写了该方法,所以直接调用cleaned_data获取值即可
            data = obj.cleaned_data
            error = obj.errors
            print('错误信息',error)
            print('正确信息:',data)
            return render(request, 'fm.html', {"obj": obj})

    templates/fm.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        {#    模版语言一: 逐个输出内容#}
            <h5>模版语言,逐个输出</h5>
            {{ obj.username }}
            {{ obj.email }}
    <hr>
        {# 模版语言二: 一次性输出全部内容,如果是as_p,则是在P标签内,as_ul是ul标签 #}
            <h5>模版语言,一次性配合lable标签输出全部字段</h5>
            {{ obj.as_p }}
            {{ obj.as_ul }}
            <table>{{ obj.as_table }}</table>
    <hr>
            <form action="/fm/" method="post">
                {{ obj.as_p }}
                <input type="submit" value="提交"/>
            </form>
    </body>
    </html>

    页面显示;

    image

    初始化数据库

    python manage.py makemigrations
    python manage.py migrate
    

    Form操作之is_valid()源码解析

    进入full_clean()方法

    image

    full_clean()方法:

    image

    _clean_fields()

    image

    image

    add_error(name,e)

    image

    image

    _clean_form():

    image

    _post_form()

    image

    Form操作之前台下拉框实时显示数据库内容

    问题现象:无法获取数据库内最新的数据

    imageimage

    解决一: 调用父类的构造方法,每次调用函数之前重新获取数据

    class Fm(forms.Form):
        username = fields.CharField(max_length=32, label='用户名')
        email = fields.EmailField(label='邮箱')
        user_type=fields.ChoiceField(choices=models.UT.objects.values_list('id', 'caption'))
    
        def __init__(self, *args, **kwargs):
            super(Fm, self).__init__(*args, **kwargs)
            self.fields['user_type'].widget.choices = models.UT.objects.all().values_list('id', 'caption')

    image

    image

    最终显示内容:

    image

     

    附完整源码:

    settings.py

    INSTALLED_APPS = [
       ...
     'app01',   # 注册app
    ]
    STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)  # 现添加的配置,这里是元组,注意逗号
    TEMPLATES = [
       ...
       'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ]

    urls.py

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url, include
    from app01 import views
    urlpatterns = [
       url('fm/', views.fm),
    ]

    views.py

    from django.shortcuts import render, redirect, HttpResponse
    from app01 import models
    class Fm(forms.Form):
        username = fields.CharField(max_length=32, label='用户名')
        email = fields.EmailField(label='邮箱')
        user_type=fields.ChoiceField(choices=models.UT.objects.values_list('id', 'caption'))
        # 方案一:
        def __init__(self, *args, **kwargs):
            super(Fm, self).__init__(*args, **kwargs)
            self.fields['user_type'].widget.choices = models.UT.objects.all().values_list('id', 'caption')
        # 方案二:
        from django.forms import models as filed_models
        # 这里的all()返回的是一个对象,前台页面显示的始终是object,但是看源码又有value值
        # 同时这里的limit_choices_to并无明显效果显示,在ModelForm里面效果显著    
    user_type2 = filed_models.ModelChoiceField(queryset=models.UT.objects.all(),
                                                   to_field_name='caption',
                                                   limit_choices_to={'id':'(1,3)'},)
        # 多选框
        user_type3 = filed_models.ModelMultipleChoiceField(queryset=models.UT.objects.all(),
                                                   to_field_name='caption',
                                                   limit_choices_to={'id': '(1,3)'}, )
    
    def fm(request):
        if request.method == "GET":
            obj = Fm()
            return render(request, 'fm.html', {"obj": obj})

    models.py

    from django.db import models
    class U(models.Model):
        id = models.AutoField(primary_key=True)  # AutoField必须是主键,才能自定义该列
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        userType = models.ForeignKey("UT", on_delete=True)  # 1对多[无法用自定义,有约束关系]
    
    class UT(models.Model):
        caption = models.CharField(max_length=32)
        def __str__(self):
            return self.caption

    templates/fm.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        {#    模版语言一: 逐个输出内容#}
            <h5>模版语言,逐个输出</h5>
            {{ obj.username }}
            {{ obj.email }}
    <hr>
        {# 模版语言二: 一次性输出全部内容,如果是as_p,则是在P标签内,as_ul是ul标签 #}
            <h5>模版语言,一次性配合lable标签输出全部字段</h5>
            {{ obj.as_p }}
            {{ obj.as_ul }}
            <table>{{ obj.as_table }}</table>
    <hr>
            <form action="/fm/" method="post">
                {{ obj.as_p }}
                <input type="submit" value="提交"/>
            </form>
    </body>
    </html>

    页面显示;

    image

    初始化数据库

    python manage.py makemigrations
    python manage.py migrate
    

     

    Form操作更多参考 :http://www.cnblogs.com/wupeiqi/articles/6144178.html

  • 相关阅读:
    创建发布Webservice以及wsimport工具
    Webservice介绍
    MongoDB简单认识
    Java集合的介绍
    Java虚拟机(JVM)体系结构概述及各种性能参数优化总结
    Java虚拟机(JVM)
    eclipse, idea安装lombok插件
    在window下, Java调用执行bat脚本
    python3对多线程处理
    Selenium常见元素定位方法和操作的学习介绍
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9418162.html
Copyright © 2011-2022 走看看