Django中的Form表单

方式1:

from django.shortcuts import render,HttpResponse,redirect
from django.views import View
from django.core import serializers
import json

# Create your views here.
# class LoginView(View):
#     def dispatch(self, request, *args, **kwargs):
#         print('before')
#         response = super(LoginView,self).dispatch(request,*args,**kwargs)
#         print('after')
#         return response
#
#     def get(self,request,*args,**kwargs):
#         print('GET')
#         return render(request,'login.html')
#
#     def post(self,request,*args,**kwargs):
#         print('POST')
#         user = request.POST.get('user')
#         pwd = request.POST.get('pwd')
#         if user == 'alex' and pwd == '123':
#             request.session['username'] = user
#             return redirect('/index/')
#         else:
#             return render(request,'login.html',{'msg':'登陆失败'})
#
# def auth(func):
#     def inner(request,*args,**kwargs):
#         user =  request.session.get('username')
#         if user:
#             return func(request,*args,**kwargs)
#         else:
#             return redirect('/login/')
#     return inner
#
#
# """
# 在Django的CBV里面引入装饰器需要用到固定的格式
# """
#
# from django.utils.decorators import method_decorator
#
# class IndexView(View):
#     """
#     继承View的原因:要用到as_view等方法
#     """
#     @method_decorator(auth) #这里相当于一个总闸门
#     def dispatch(self, request, *args, **kwargs):
#         response = super(IndexView, self).dispatch(request, *args, **kwargs)
#         return response
#
#
#     # @method_decorator(auth) => 可以直接放在这里加
#     def get(self,request,*args,**kwargs):
#         return HttpResponse(request.session['username'])
from app01 import  models

def users(request):
    return render(request,'users.html')


def get_users(request):
    """
    function:我们需要加上response指定标准
    """
    response = {'status':True,'data':None,'msg':None}
    try:
        user_list = models.UserInfo.objects.values('id','username')
        # user_list = list(user_list),如果正确,则将user_list的数值赋值给data
        response['data'] = list(user_list)
    except Exception as e:
        response['status'] = False
        response['msg'] = str(e)

    data = json.dumps(response)
    return HttpResponse(data)




from django.forms import Form
from django.forms import fields
from django.forms import widgets


class UserForm(Form):
    #通过这个类可以帮我们生成相应的html标签
    user = fields.CharField(required=True)
    email = fields.EmailField(required=True)
    user_type = fields.ChoiceField(choices=[(1,'上海'),(2,'北京',),(3,'广州')])


class AddUserView(View):
    def get(self,request,*args,**kwargs):
        form = UserForm()
        return render(request,'add_user.html',{'form':form})

    def post(self,request,*args,**kwargs):
        form = UserForm(data=request.POST)
        #将用户提交的数据和UserForm中定义的规则进行匹配
        if form.is_valid():
            # 如果用户提交的数据正确,则获取用户所有的数据
            print(form.cleaned_data)
            return redirect('/xxxx.html')
        else:
            #显示相应的错误信息
            print(form.errors)
            # 此时前端自动将错误信息给显示出来了
            return render(request,'add_user.html',{"form":form})

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>添加用户</h1>
    <form method="POST" novalidate>
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="提交">
    </form>
</body>
</html>

运行结果:
这里写图片描述
问题:form.as_p不能够定制,虽然通过form.as_p可以生成form中所有的html标签,但是不能够定制,也不能够样式渲染。

   def as_p(self):
       "Returns this form rendered as HTML <p>s."
       return self._html_output(
           normal_row='<p%(html_class_attr)s>%(label)s %(field)s%(help_text)s</p>',
           error_row='%s',
           row_ender='</p>',
           help_text_html=' <span class="helptext">%s</span>',
           errors_on_separate_row=True)

改进1:(后端不做任何的改进,仅仅前端做改进)

<body>
    <h1>添加用户</h1>
    <form method="POST" novalidate>
        {% csrf_token %}
        {#  用户自定制相应的内容,form.errors.user实际上包含了很多的错误信息 #}
        <p>用户名:{{ form.user }}{{ form.errors.user }}</p>
        <p>邮箱:{{ form.email }}{{ form.errors.email.0 }}</p>
        <p>用户类型:{{ form.user_type }}{{ form.errors.user_type.0 }}</p>
        <input type="submit" value="提交">
    </form>
</body>

效果展示:
这里写图片描述
改进2:将错误的提示信息用中文显示出来。
后台:

from django.shortcuts import render,HttpResponse,redirect
from django.views import View
from django.core import serializers
import json

# Create your views here.
# class LoginView(View):
#     def dispatch(self, request, *args, **kwargs):
#         print('before')
#         response = super(LoginView,self).dispatch(request,*args,**kwargs)
#         print('after')
#         return response
#
#     def get(self,request,*args,**kwargs):
#         print('GET')
#         return render(request,'login.html')
#
#     def post(self,request,*args,**kwargs):
#         print('POST')
#         user = request.POST.get('user')
#         pwd = request.POST.get('pwd')
#         if user == 'alex' and pwd == '123':
#             request.session['username'] = user
#             return redirect('/index/')
#         else:
#             return render(request,'login.html',{'msg':'登陆失败'})
#
# def auth(func):
#     def inner(request,*args,**kwargs):
#         user =  request.session.get('username')
#         if user:
#             return func(request,*args,**kwargs)
#         else:
#             return redirect('/login/')
#     return inner
#
#
# """
# 在Django的CBV里面引入装饰器需要用到固定的格式
# """
#
# from django.utils.decorators import method_decorator
#
# class IndexView(View):
#     """
#     继承View的原因:要用到as_view等方法
#     """
#     @method_decorator(auth) #这里相当于一个总闸门
#     def dispatch(self, request, *args, **kwargs):
#         response = super(IndexView, self).dispatch(request, *args, **kwargs)
#         return response
#
#
#     # @method_decorator(auth) => 可以直接放在这里加
#     def get(self,request,*args,**kwargs):
#         return HttpResponse(request.session['username'])
from app01 import  models

def users(request):
    return render(request,'users.html')


def get_users(request):
    """
    function:我们需要加上response指定标准
    """
    response = {'status':True,'data':None,'msg':None}
    try:
        user_list = models.UserInfo.objects.values('id','username')
        # user_list = list(user_list),如果正确,则将user_list的数值赋值给data
        response['data'] = list(user_list)
    except Exception as e:
        response['status'] = False
        response['msg'] = str(e)

    data = json.dumps(response)
    return HttpResponse(data)




from django.forms import Form
from django.forms import fields
from django.forms import widgets


class UserForm(Form):
    #通过这个类可以帮我们生成相应的html标签
    user = fields.CharField(
        required=True,
        #自定义错误信息
        error_messages={'required':'用户名不能为空'}
    )
    email = fields.EmailField(
        required=True,
        #自定义错误信息
        error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'}
    )
    ip  = fields.GenericIPAddressField(
        required=True,
        # 自定义错误信息
        error_messages={'required': 'IP不能为空', 'invalid': 'IP格式错误'}
    )
    user_type = fields.ChoiceField(choices=[(1,'上海'),(2,'北京',),(3,'广州')])


class AddUserView(View):
    def get(self,request,*args,**kwargs):
        #创建的类对象自动具有user、email和user_type三个属性
        form = UserForm()
        return render(request,'add_user.html',{'form':form})

    def post(self,request,*args,**kwargs):
        form = UserForm(data=request.POST)
        #将用户提交的数据和UserForm中定义的规则进行匹配
        if form.is_valid():
            # 如果用户提交的数据正确,则获取用户所有的数据
            print(form.cleaned_data)
            #{'user': 'fds', 'user_type': '1', 'email': '994343@qq.com', 'ip': '192.168.80.100'}
            return redirect('/xxxx.html')
        else:
            #显示相应的错误信息
            print(form.errors)
            # 此时前端自动将错误信息给显示出来了
            return render(request,'add_user.html',{"form":form})

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>添加用户</h1>
    <form method="POST" novalidate>
        {% csrf_token %}
        {#  用户自定制相应的内容,form.errors.user实际上包含了很多的错误信息 #}
        <p>用户名:{{ form.user }}{{ form.errors.user }}</p>
        <p>邮箱:{{ form.email }}{{ form.errors.email.0 }}</p>
        <p>IP:{{ form.ip }}{{ form.errors.ip.0 }}</p>
        <p>用户类型:{{ form.user_type }}{{ form.errors.user_type.0 }}</p>
        <input type="submit" value="提交">
    </form>
</body>
</html>

效果展示:
这里写图片描述
到现在为止,我们在加入一个编辑的功能:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
但是到现在为止还是有一个bug,这个bug就是当我的用户类型增加之后,在添加当中还是只显示以前的两个类型,只有通过重启之后才可以看到最新的类型:
解决方法:

class UserForm(Form):
    def __init__(self,*args,**kwargs):
        super(UserForm,self).__init__(*args,**kwargs)
        self.fields['ut_id'].choices = \
            models.UserType.objects.values_list('id','title')

    #通过这个类可以帮我们生成相应的html标签
    #字段名应该和数据库的名字一致
    #静态字段加载的时候只有在第一次才会执行
    username = fields.CharField(
        required=True,
        #自定义错误信息
        error_messages={'required':'用户名不能为空'}
    )
    password = fields.EmailField(
        required=True,
        #自定义错误信息
        error_messages={'required':'密码不能为空','invalid':'密码格式错误'}
    )

    # user_type = fields.ChoiceField(choices=[(1,'上海'),(2,'北京',),(3,'广州')])
    ut_id = fields.ChoiceField(choices=models.UserType.objects.values_list('id','title'))

总结:4个步骤1个问题

        总结:
            1. 创建Form类(本质就是正则表达式的集合)


            2. 只是生成HTML标签: 添加页面
                form = MyForm()

                {{form.xx}}

            3. 带默认值的HTML标签: 编辑页面
                form = MyForm(initial={'xx': xxx})

                {{form.xx}}

            4. 提交数据
                form = MyForm(data=request.POST)

                if form.is_valid():
                    print(form.cleaned_data)
                else:
                    print(form.errors)

            问题:下拉框数据无法实时更新
                class UserForm(Form):
                    username = fields.CharField(
                        required=True,
                        error_messages={'required':'用户名不能为空'}
                    )
                    password = fields.CharField(
                        required=True,
                        error_messages={'required': '邮箱不能为空','invalid':'邮箱格式错误'}
                    )

                    ut_id = fields.ChoiceField(choices=[])

                    def __init__(self,*args,**kwargs):
                        super(UserForm,self).__init__(*args,**kwargs)

                        self.fields['ut_id'].choices = models.UserType.objects.values_list('id','title')

到现在为止,我们可以进行一对一,一对多的操作了,我们此时如何进行input的定制操作呢?
下面是不能进行class等修饰的

<form method="POST" novalidate>
    {% csrf_token %}
    {#  编辑的时候应该有默认值  #}
    <p>用户名:{{ form.username }}{{ form.errors.username.0 }}</p>
    <p>邮箱:{{ form.password }}{{ form.errors.password.0 }}</p>
    <p>用户类型:{{ form.ut_id }}{{ form.errors.ut_id.0 }}</p>
    <p>用户角色:{{ form.role_id }}{{ form.errors.role_id.0 }}</p>
    <input type="submit" value="提交">
</form>

通过下面我们就可以将form表单嵌套在bootStrap当中:

class UserForm(Form):
    def __init__(self,*args,**kwargs):
        super(UserForm,self).__init__(*args,**kwargs)
        self.fields['ut_id'].choices = \
            models.UserType.objects.values_list('id','title')
        self.fields['role_id'].choices =\
            models.Role.objects.values_list('id','caption')
    #通过这个类可以帮我们生成相应的html标签
    #字段名应该和数据库的名字一致
    #静态字段加载的时候只有在第一次才会执行
    username = fields.CharField(
        required=True,
        #自定义错误信息
        error_messages={'required':'用户名不能为空'},
        widget=widgets.TextInput(attrs={'class':'form-control'})
    )
    password = fields.EmailField(
        required=True,
        #自定义错误信息
        error_messages={'required':'密码不能为空','invalid':'密码格式错误'},
        widget = widgets.Textarea(attrs={'class': 'form-control'})
    )
    # fields.EmailField()
    # fields.GenericIPAddressField(protocol='ipv4')
    # user_type = fields.ChoiceField(choices=[(1,'上海'),(2,'北京',),(3,'广州')])
    ut_id = fields.ChoiceField(
        choices=[],
        widget=widgets.Select(attrs={'class':'form-control'})
    )

    role_id = fields.MultipleChoiceField(
        choices=[],
        widget=widgets.SelectMultiple(attrs={'class': 'form-control'})
                                         )

综上我们的Form表单实际上有很多的功能,但是下面我们只使用Form表单验证的功能。
示例:只用表单验证的功能(Ajax提交)
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值