Django Form
案例需求:
出版社,作者,书籍 后台管理
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() def __str__(self): return self.name class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() def __str__(self): return '%s %s' % (self.first_name, self.last_name) class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField('Author') publisher = models.ForeignKey('Publisher') publication_date = models.DateField() def __str(self): return self.title
# books/templates/books/publisher_add.html <form method="post"> {% csrf_token %} <p style="color: red">{{ error_message }}</p> <label for="name">Name: </label><input id="name" name="name" type="text"/><br/> <label for="address">Address: </label><input id="address" name="address" type="text"/><br/> <label for="city">City: </label><input id="city" name="city" type="text"/><br/> <label for="state_province">State_province: </label><input id="state_province" name="state_province" type="text"/><br/> <label for="country">Country: </label><input id="country" name="country" type="text"/><br/> <label for="website">Website: </label><input id="website" name="website" type="text"/><br/> <input type="submit" value="Submit"/> </form> # books/views.py def publisher_add(request): if request.method == "POST": name = request.POST.get('name', '') address = request.POST.get('address', '') city = request.POST.get('city', '') state_province = request.POST.get('state_province', '') country = request.POST.get('country', '') website = request.POST.get('website', '') error_message = [] if not name: error_message.append('Name is required') if len(name) > 30: error_message.append('Name should be shorter than 30') if not address: error_message.append('Address ia required') if len(address) > 50: error_message.append('Address should be shorter than 50') if error_message: return render(request, 'books/publisher_add.html', {'error_message': error_message}) else: return HttpResponse('添加成功') else: return render(request, 'books/publisher_add.html')
分析:
-
验证用户输入
-
返回用户error
-
html构造form
-
验证用户输入和model的约束重复
-
代码冗长
用Django Form来解决这些问题:
先了解Django Form组件常见用法,models.Model是转换为sql语句,那forms.Form是做什么的呢
说明:
-
class NameForm(forms.Form),自定义Form类
-
form = NameForm(),实例化定义From类
-
form.is_bound,定义Form时是否传入数据,如form=NameForm() 为False;form=NameForm({'key':'value'})为True
-
from.as_p(),form.as_table(),form.as_ul,from对象可以转换为html标签
-
form.is_valid(),验证输入数据合法性
-
form.cleaned_data['key'],必须先执行is_valid(),输入合法后会转换为Python合适的数据类型,并以字典分装
-
from.errors,输入不合法
需求实现:
# forms.py from django import forms class PublisherForm(forms.Form): name = forms.CharField(label='Your name', max_length=30) address = forms.CharField(max_length=50) city = forms.CharField(max_length=60) state_province = forms.CharField(max_length=30) country = forms.CharField(max_length=50) website = forms.CharField(max_length=50) # views.py from django.shortcuts import render, redirect from django.http import HttpResponse, HttpResponseRedirect from .forms import PublisherForm from .models import Publisher def publisher_add(request): if request.method == "POST": form = PublisherForm(request.POST) # 用户数据获取 if form.is_valid(): # 用户数据校验 publisher = Publisher( name=form.cleaned_data['name'], address=form.cleaned_data['address'], city=form.cleaned_data['city'], state_province=form.cleaned_data['state_province'], country=form.cleaned_data['country'], website=form.cleaned_data['website'], ) publisher.save() return HttpResponse('添加成功') else: return render(request, 'books/publisher_add.html', {'form': form}) else: form = PublisherForm() return render(request, 'books/publisher_add.html', {'form': form}) # books/publisher_add.html <form method="post"> <h1>添加出版社</h1> {{ form }} {% csrf_token %} <input type="submit" value="提交"/> </form>
Form解决的问题:
-
用户的输入不用手动获取
-
用户输入的验证自动完成
-
表单编写不用手写html
带来或未解决问题:
-
需要编写Form结构(和models重复)
-
需要手动获取内容保存到数据库
再来一个案例:
前端模板可以整体使用 {{ form }},也可以单独使用 { form.field.相关属性}}
# forms.py from django import forms class ContactForm(forms.Form): subject = forms.CharField(max_length=100,help_text='dadada') message = forms.CharField(widget=forms.Textarea) sender = forms.EmailField() cc_myself = forms.BooleanField(required=False) # views.py def sendmail(request): print(request.method) if request.method == "POST": print('**********') form = ContactForm(request.POST) if form.is_valid(): subject = form.cleaned_data['subject'] message = form.cleaned_data['message'] sender = form.cleaned_data['sender'] cc_myself = form.cleaned_data['cc_myself'] recipients = ['nin@jianxin.com.cn'] if cc_myself: recipients.append(sender) # send_mail() return HttpResponse('发送成功') else: return render(request, 'books/sendmail_manual.html',{'form':form}) elif request.method == "GET": form = ContactForm() return render(request, 'books/sendmail_manual.html', {'form': form}) # books/templates/sendmail_manual.html <form method="post" action="{% url 'books:sendmail' %}"> {% csrf_token %} {{ form.non_field_errors }} <div> {{ form.subject.errors }} <label for="{{ form.subject.id_for_label }}">Email Subject: </label>{{ form.subject }}<br/> <div> <strong>form.subject.label---></strong>{{ form.subject.label }}<br/> <strong>form.subject.label_tag---></strong>{{ form.subject.label_tag }}<br/> <strong>form.subject.id_for_label---></strong>{{ form.subject.id_for_label }}<br/> <strong>form.subject.value---></strong>{{ form.subject.value }}<br/> <strong>form.subject.html_name---></strong>{{ form.subject.html_name }}<br/> <strong>form.subject.help_text---></strong>{{ form.subject.help_text }}<br/> <strong>form.subject.errors---> </strong>{{ form.subject.errors }}<br/> </div> </div> <div> {{ form.message.errors }} <label for="{{ form.message.id_for_label }}">Your message: </label> {{ form.message }} </div> <div> {{ form.sender.errors }} <label for="{{ form.sender.id_for_label }}">Your Email Address: </label> {{ form.sender }} </div> <div> {{ form.cc_myself.errors }} <label for="{{ form.cc_myself.id_for_label }}">CC yourself?: </label> {{ form.cc_myself }} </div> <div> <input type="submit" value="Submit"/> </div> </form>
说明:
-
forms.EmailField(),前端输入字符串必须符合email格式
-
forms.CharField(widget=forms.Textarea),widget用处很大
-
forms.BooleanField(required=False),转换为type='radio',required=False 可选
form和field的一些属性
-
{{ form.non_field_errors }} 对应的是 ModelForm联合验证方法 def clean()
-
{{ form.errors }}
-
{{ field.label }}
-
{{ field.label_tag }}
-
{{ field.id_for_label }}
-
{{ field.value }}
-
{{ field.html }}
-
{{ field.help_text}}
-
{{ field.errors}}
https://docs.djangoproject.com/en/1.11/topics/forms/#looping-over-the-form-s-fields
field 手动校验:
内置 form field 和widgets:
时常浏览
posted on 2017-09-12 14:45 Jonathan1314 阅读(197) 评论(0) 编辑 收藏 举报