Django表单processing

LearningDjango表单class, 表单模板, 表单verification and ModelForm

Django表单overview

表单 is Webapplicationin用于收集user输入 important component. Djangoproviding了强 big 表单processingfunctions, including表单class定义, 表单verification, 表单渲染etc..

提示

Django 表单system可以helpingDevelopment者 fast 速creationsecurity, reliable 表单, 避免重复writingHTML表单 and verification逻辑.

表单class

in Djangoin, 表单 is throughPythonclass来定义 , inheritance自django.forms.Formclass.

creation表单class

# blog/forms.py
from django import forms

class CommentForm(forms.Form):
    name = forms.CharField(label='姓名', max_length=100)
    email = forms.EmailField(label='邮箱')
    content = forms.CharField(label='评论 in 容', widget=forms.Textarea)
    
    # 自定义verificationmethod
    def clean_name(self):
        name = self.cleaned_data.get('name')
        if len(name) < 2:
            raise forms.ValidationError('姓名 long 度不能 few 于2个字符')
        return name

常用表单字段class型

  • CharField: 文本输入框, 用于接收 short 文本.
  • TextField: many 行文本输入框, 用于接收 long 文本.
  • EmailField: 邮箱输入框, 会自动verification邮箱格式.
  • URLField: URL输入框, 会自动verificationURL格式.
  • IntegerField: 整数输入框.
  • FloatField: 浮点数输入框.
  • DecimalField: 十进制 small 数输入框.
  • BooleanField: 复选框, 用于接收boolean值.
  • DateField: 日期输入框.
  • DateTimeField: 日期时间输入框.
  • ChoiceField: under 拉选择框, 用于 from 预定义选项in选择.
  • MultipleChoiceField: many 选框, 用于 from 预定义选项in选择 many 个.
  • FileField: file on 传字段.
  • ImageField: graph片 on 传字段, 会自动verificationgraph片格式.

表单字段选项

  • label: 表单字段 tag文本.
  • required: is 否 for 必填字段, 默认 for True.
  • max_length: 最 big long 度.
  • min_length: 最 small long 度.
  • initial: 初始值.
  • help_text: helping文本, 显示 in 字段 under 方.
  • widget: 表单字段 HTML部件, 用于自定义字段 渲染方式.
  • validators: 自定义verification器list.

in 视graphinusing表单

in 视graphin, 需要creation表单instance, 并processing表单 submitting and verification.

# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import BlogPost, Comment
from .forms import CommentForm

def post_detail(request, pk):
    post = get_object_or_404(BlogPost, pk=pk)
    comments = post.comments.all()
    
    if request.method == 'POST':
        # creation表单instance并填充data
        form = CommentForm(request.POST)
        if form.is_valid():
            # 获取verification after  data
            cleaned_data = form.cleaned_data
            # creation评论object
            comment = Comment(
                post=post,
                name=cleaned_data['name'],
                email=cleaned_data['email'],
                content=cleaned_data['content']
            )
            comment.save()
            # 重定向 to 当 before 页面, 避免表单重复submitting
            return redirect('post_detail', pk=pk)
    else:
        # creation空表单instance
        form = CommentForm()
    
    return render(request, 'blog/post_detail.html', {
        'post': post,
        'comments': comments,
        'form': form
    })

in 模板in渲染表单

Djangoproviding了 many 种方式 in 模板in渲染表单.

自动渲染表单

<!-- 渲染整个表单 -->
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}  <!-- 每个字段serving asptag -->
    <!-- other渲染方式: 
    {{ form.as_table }}  <!-- 每个字段serving astable行 -->
    {{ form.as_ul }}     <!-- 每个字段serving asullist项 -->
    -->
    <button type="submit">submitting评论</button>
</form>

手动渲染表单字段

<form method="post">
    {% csrf_token %}
    
    <div class="form-group">
        <label for="{{ form.name.id_for_label }}">{{ form.name.label }}</label>
        {{ form.name }}  <!-- 渲染单个字段 -->
        {% if form.name.errors %}
            <div class="error">{{ form.name.errors }}</div>
        {% endif %}
        <small class="help-text">{{ form.name.help_text }}</small>
    </div>
    
    <div class="form-group">
        <label for="{{ form.email.id_for_label }}">{{ form.email.label }}</label>
        {{ form.email }}
        {% if form.email.errors %}
            <div class="error">{{ form.email.errors }}</div>
        {% endif %}
    </div>
    
    <div class="form-group">
        <label for="{{ form.content.id_for_label }}">{{ form.content.label }}</label>
        {{ form.content }}
        {% if form.content.errors %}
            <div class="error">{{ form.content.errors }}</div>
        {% endif %}
    </div>
    
    <button type="submit">submitting评论</button>
</form>

表单errorprocessing

<!-- 显示表单 非字段error -->
{% if form.non_field_errors %}
    <div class="error">{{ form.non_field_errors }}</div>
{% endif %}

ModelForm

ModelForm is Djangoproviding 一个强 big functions, 它可以根据model自动生成表单.

creationModelForm

# blog/forms.py
from django import forms
from .models import BlogPost

class BlogPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ['title', 'content', 'is_published']  # 指定要package含 字段
        #  or 者排除某些字段
        # exclude = ['pub_date', 'update_date']
        
        # 自定义字段tag and helping文本
        labels = {
            'title': '文章标题',
            'content': '文章 in 容',
            'is_published': ' is 否release'
        }
        help_texts = {
            'title': '请输入文章标题',
            'content': '请输入文章 in 容',
            'is_published': '勾选表示release这篇文章'
        }
        # 自定义widget
        widgets = {
            'content': forms.Textarea(attrs={'rows': 10, 'cols': 80})
        }

in 视graphinusingModelForm

# blog/views.py
from django.shortcuts import render, redirect
from .forms import BlogPostForm

def create_post(request):
    if request.method == 'POST':
        form = BlogPostForm(request.POST)
        if form.is_valid():
            # 保存表单data to datalibrary
            form.save()
            return redirect('post_list')
    else:
        form = BlogPostForm()
    
    return render(request, 'blog/create_post.html', {'form': form})

# update文章
def update_post(request, pk):
    post = get_object_or_404(BlogPost, pk=pk)
    if request.method == 'POST':
        form = BlogPostForm(request.POST, instance=post)  # 传入instanceparameter表示update现 has object
        if form.is_valid():
            form.save()
            return redirect('post_detail', pk=pk)
    else:
        form = BlogPostForm(instance=post)  # 传入instanceparameter表示using现 has object data填充表单
    
    return render(request, 'blog/update_post.html', {'form': form, 'post': post})

ModelForm模板

<!-- blog/templates/blog/create_post.html -->
{% extends 'blog/base.html' %}

{% block title %}creation文章{% endblock %}

{% block content %}
    <h1>creation new 文章</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">creation文章</button>
    </form>
{% endblock %}

表单verification

Django表单systemproviding了强 big verificationfunctions, including字段级verification and 表单级verification.

字段级verification

through in 表单classin定义clean_字段名method来implementation字段级verification:

def clean_email(self):
    email = self.cleaned_data.get('email')
    if '@example.com' in email:
        raise forms.ValidationError('不允许usingexample.com邮箱')
    return email

表单级verification

through重写表单class cleanmethod来implementation表单级verification:

def clean(self):
    cleaned_data = super().clean()
    password1 = cleaned_data.get('password1')
    password2 = cleaned_data.get('password2')
    
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError('两次输入 password不一致')
    
    return cleaned_data

表单样式定制

可以through自定义widget attrsproperty来添加CSSclass and otherHTMLproperty:

# 方式1:  in 表单classin定义
class CommentForm(forms.Form):
    name = forms.CharField(
        label='姓名', 
        max_length=100,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入姓名'})
    )
    # other字段...

# 方式2:  in 视graphin动态添加
form = CommentForm()
form.fields['name'].widget.attrs.update({'class': 'form-control'})
form.fields['email'].widget.attrs.update({'class': 'form-control'})
form.fields['content'].widget.attrs.update({'class': 'form-control', 'rows': 5})

练习 1: creation评论表单

  1. in blogapplicationincreationCommentmodel, package含name, email, content, post ( out 键) , created_at字段.
  2. creationCommentForm表单class, 用于submitting评论.
  3. in post_detail视graphin添加评论processing逻辑.
  4. in post_detail.html模板in添加评论表单.
  5. test评论functions.

练习 2: creation文章management表单

  1. creationBlogPostForm ModelForm, 用于creation and update文章.
  2. creationcreate_post and update_post视graph.
  3. creation for 应 模板.
  4. test文章 creation and updatefunctions.