Django框架全面讲解 -- Form

django中的Form一般有两种功能:

输入html
验证用户输入
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError

def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')

class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'标题不能为空',
                                            'min_length': u'标题最少为5个字符',
                                            'max_length': u'标题最多为20个字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'标题5-20个字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手机不能为空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

# 举个栗子

def publish(request):
    ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
    if request.method == 'POST':
        request_form = PublishForm(request.POST)
        if request_form.is_valid():
            request_dict = request_form.clean()
            print request_dict
            ret['status'] = True
        else:
            error_msg = request_form.errors.as_json()
            ret['error'] = json.loads(error_msg)
    return HttpResponse(json.dumps(ret))

利用Form还可以自动生成前端的input标签:

from app01 import models
from django import forms

class Form1(forms.Form):
    user = forms.CharField(
        widget=forms.TextInput(attrs={'class':'c1'}), # 给标签添加属性
        error_messages={'required':'用户名不能为空'}, # 自定义错误输出
    )
    pwd = forms.CharField(max_length=4, min_length=2)
    email = forms.EmailField(error_messages={'required':'邮箱不能为空', 'invalid':'邮箱格式错误'})

    memo = forms.CharField(
        widget=forms.Textarea()
    )
    # user_type_choice = (
    #     (0, '普通用户'),
    #     (1, '高级用户'),
    # )
    user_type_choice = models.BookType.objects.values_list("id", "caption")
    # 这样并不能跟数据库实时同步,因为静态字段不更新
    book_type = forms.CharField(
        widget=forms.widgets.Select(choices=user_type_choice)
    )
    def __init__(self, *args, **kwargs):
        super(Form1, self).__init__(*args, **kwargs)
        # 让选项框跟数据库进行实时联动,解决上一行注释的问题
        self.fields['book_type'] = forms.CharField(
            widget=forms.widgets.Select(choices=models.BookType.objects.values_list("id", "caption"))
        )
def form1(request):

    if request.method == "POST":
        # 获取请求做验证
        f = Form1(request.POST)
        if f.is_valid():
            print(f.cleaned_data)
        else:
            pass
            # print(f.errors['user'][0])
            # print(f.errors['pwd'][0])
        return render(request, "form1.html", {'error': f.errors, 'form':f})
    else:
        f = Form1()
        return render(request, 'form1.html',{'form':f})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .input-group{
            position: relative;
            padding: 23px;

        }
        .input-group input{
            width: 200px;
            display: inline-block;
        }
        .input-group span{
            display: inline-block;
            position: absolute;
            height: 20px;
            background-color:coral;
            color: white;
            bottom: 1px;
            left: 22px;
            width: 204px;


        }
    </style>
</head>
<body>
    <div>
        <form action="/form/" method="post">
            <div class="input-group">
{#                <input type="text" name="user"/>#}
                {{ form.user }}
                {% if error.user.0 %}
                <span>{{ error.user.0 }}</span>
                {% endif %}
            </div>
            <div class="input-group">
{#                <input type="text" name="pwd"/>#}
                {{ form.pwd }}
                {% if error.pwd.0 %}
                <span>{{ error.pwd.0 }}</span>
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.email }}
                {% if error.email.0 %}
                <span>{{ error.email.0 }}</span>
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.memo }}
                {% if error.memo.0 %}
                <span>{{ error.memo.0 }}</span>
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.book_type }}
                {% if error.book_type.0 %}
                <span>{{ error.book_type.0 }}</span>
                {% endif %}
            </div>
            <input type="submit" value="提交"/>
        </form>
    </div>

</body>
</html>

扩展:ModelForm

在使用Model和Form时,都需要对字段进行定义并指定类型,通过ModelForm则可以省去From中字段的定义

class AdminModelForm(forms.ModelForm):

    class Meta:
        model = models.Admin
        #fields = '__all__'
        fields = ('username', 'email')

        widgets = {
            'email' : forms.PasswordInput(attrs={'class':"alex"}),
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值