from和modelform的用法和介绍

from和modelform的用法和介绍

 

一 form

1. form的作用

  1. 生成HTML代码
  2. 帮我们做数据有效性的校验
  3. 保留上次输入内容,显示错误提示

2. form组件校验数据有效性
  1. 内置的校验规则
  1. require=True 该字段必填
  2. max_length 该字段的最大长度
  3. min_length 该字段的最小长度

 

 2. 自定义校验规则
  1. 如手机号的格式 利用内置的正则校验器
  from django.core.validators import RegexValidator
  validators=[RegexValidator(r'^1[356789]\d{9}$', "手机号码格式不正确")],

 


3. 使用钩子函数做校验
 1. 局部钩子(hook)
           在form类内部定义一个 clean_字段名() 方法

 例子

复制代码
复制代码
  #自定义一个局部钩子函数含有alex的关键字不能提交
    def clean_title(self):
        value=self.cleaned_data.get("title")  #获取书名
        if "alex" in value:
            raise ValidationError("ALEX以备和谐")
        else:
            return value
复制代码
复制代码

 

 2. 全局钩子
       在form类内部定义一个 clean() 方法

4. form组合如何给html标签设置默认值

  1. 每一个字段设置默认值
  initial="默认值"

实例:关于使用form的例子,使用form之前可以自己写一个单独的form类,我这里一添加book为例:

1 form.py

 1 from django import forms
 2 from app01 import models
 3 from django.core.exceptions import ValidationError #注册功能
 4 from django.core.validators import RegexValidator # 检验手机号码是否正确
 5 
 6 # 自己定义一个form类
 7 class BookForm(forms.Form):
 8     title=forms.CharField(
 9         max_length=12,
10         min_length=2,
11         # 如果想让网页显示中文就加上label
12         label="书名",
13         initial="填写书名",
14         # 给tttle生成的input标签加上一个class类
15         widget=forms.widgets.TextInput(attrs={"class":"form-control"})
16     )
17     publisher_date=forms.DateField(
18         label="出版日期",
19         # widget 插件
20         widget=forms.widgets.DateInput(attrs={"type":"date","class":"form-control"})
21     )
22     phone=forms.CharField(
23         max_length=11,
24         validators=[RegexValidator(r'^1[356789]\d{9}$',"手机号码格式不正确")],  # 限制手机号格式
25         widget = forms.widgets.TextInput(attrs={"class": "form-control"})
26     )
27     # 用modelchoicefield可以实时显示到页面上面当数据库增加的时候
28     publisher = forms.ModelChoiceField(
29         queryset=models.Publisher.objects.all(),
30         widget=forms.widgets.Select(attrs={"class": "form-control"}),
31     )
32     authors=forms.ModelMultipleChoiceField(
33         queryset=models.Author.objects.all(),
34         widget=forms.widgets.SelectMultiple(attrs={"class": "form-control"})
35     )
36     #自定义一个局部钩子函数含有alex的关键字不能提交
37     def clean_title(self):
38         value=self.cleaned_data.get("title")  #获取书名
39         if "alex" in value:
40             raise ValidationError("ALEX以备和谐")
41         else:
42             return value
View Code

2 views.py里面的配置做了一些改变

首先要导入你刚才自己定义的BookForm

from app01.forms import BookForm 
复制代码
复制代码
def add_book(request):
    form_obj=BookForm()
    if request.method=="POST":
        form_obj=BookForm(request.POST)
        if form_obj.is_valid(): #做数据有效性校验
            # 因为有多对多的字段,所以需要额外处理
            authors=form_obj.cleaned_data.pop("authors")
            # 创建新书籍对象
            book_obj=models.Book.objects.create(**form_obj.cleaned_data)
            # 讲书籍对象和作者建立关联
            book_obj.authors.add(*authors)
        </span><span style="color: #0000ff;">return</span> redirect(<span style="color: #800000;">"</span><span style="color: #800000;">/book_list/</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">add_book.html</span><span style="color: #800000;">"</span>,locals())</pre>
复制代码
复制代码

编辑功能

复制代码
复制代码
def edit_book(request,pk):
    book_obj=models.Book.objects.filter(id=pk).first()
    from django.forms import model_to_dict # 导入这个模块
    book_dict=model_to_dict(book_obj) # 转换成字典格式
    book_dict["publisher_date"]=book_obj.publisher_date.strftime("%Y-%m-%d") # 时间转换成字符串格式
form_obj</span>=<span style="color: #000000;">BookForm(book_dict)
</span><span style="color: #0000ff;">if</span> request.method==<span style="color: #800000;">"</span><span style="color: #800000;">POST</span><span style="color: #800000;">"</span><span style="color: #000000;">:
    form_obj</span>=<span style="color: #000000;">BookForm(request.POST) # 接受用户传来的数据
    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> form_obj.is_valid(): # 判断数据是否正常
        book_obj.title</span>=form_obj.cleaned_data.get(<span style="color: #800000;">"</span><span style="color: #800000;">title</span><span style="color: #800000;">"</span><span style="color: #000000;">)
        book_obj.publisher_id</span>=form_obj.cleaned_data.get(<span style="color: #800000;">"</span><span style="color: #800000;">publisher_date</span><span style="color: #800000;">"</span><span style="color: #000000;">)
        book_obj.publisher_id</span>=form_obj.cleaned_data.get(<span style="color: #800000;">"</span><span style="color: #800000;">publisher</span><span style="color: #800000;">"</span><span style="color: #000000;">)
        book_obj.save()
        book_obj.authors.set(form_obj.cleaned_data.get(</span><span style="color: #800000;">"</span><span style="color: #800000;">authors</span><span style="color: #800000;">"</span><span style="color: #000000;">))
        </span><span style="color: #0000ff;">return</span> redirect(<span style="color: #800000;">"</span><span style="color: #800000;">/book_list</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">return</span> render(request,<span style="color: #800000;">"</span><span style="color: #800000;">edit_book.html</span><span style="color: #800000;">"</span>,locals())</pre>
复制代码
复制代码

 

3 html里面也做了一些改变:(一些类的名字也都在forms里面给自动添加上了)

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>添加书籍</title>
 6     <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
 7 </head>
 8 <body>
 9 <div class="container">
10     <div class="row">
11         <div class="col-md-8 col-md-offset-2">
12             <h1>添加书籍</h1>
13             <form action="" method="post" novalidate autocomplete="off">
14                 {% for field in form_obj %}
15                     <div class="form-group">
16                         <label for="{{ field.id_for_label }}">{{ field.label }}</label>
17                         {{ field }}
18                         <p>{{ field.errors.0 }}</p>
19 
20                     </div>
21                 {% endfor %}
22                  <input type="submit" class="btn btn-success">
23             </form>
24 
25         </div>
26 
27     </div>
28 
29 </div>
30 
31 </body>
32 </html>
View Code

 

二 model form

1. 必须继承forms.ModelForm

2. class Meta:
  model = "一对一关联的model类名"
  fields = "__all__"
3. 实例化
  1. BookModelForm(instance=book_obj)
  2. BookModelForm(request.POST, instance=book_obj)
4. form_obj.save()

要想使用modelform,也必须先写个modelform

modelform例子:

1 modelform.py

复制代码
复制代码
from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from app01 import models

class BookModelForm(forms.ModelForm):
class Meta:
model
=models.Book
fields
="all" #model类里面所有的字段都展示
# fields="title" # 指定展示某些字段
# exclude=["title"] # 除了知道字段,其他字段都展示
# labels可以设置在网页上面显示的文字
labels={
"title":"书名",
"publisher_date":"创建日期",
"phone":"手机号",
"publisher":"出版社",
"authors":"作者",

    }
    widgets</span>={ <span style="color: #008000;">#</span><span style="color: #008000;"> 设置每个字段的插件信息</span>
        <span style="color: #800000;">"</span><span style="color: #800000;">title</span><span style="color: #800000;">"</span>: forms.widgets.TextInput(attrs={<span style="color: #800000;">"</span><span style="color: #800000;">class</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">}),
        </span><span style="color: #800000;">"</span><span style="color: #800000;">phone</span><span style="color: #800000;">"</span>: forms.widgets.TextInput(attrs={<span style="color: #800000;">"</span><span style="color: #800000;">class</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">}),
        </span><span style="color: #800000;">"</span><span style="color: #800000;">publisher</span><span style="color: #800000;">"</span>: forms.widgets.Select(attrs={<span style="color: #800000;">"</span><span style="color: #800000;">class</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">}),
        </span><span style="color: #800000;">"</span><span style="color: #800000;">authors</span><span style="color: #800000;">"</span>: forms.widgets.SelectMultiple(attrs={<span style="color: #800000;">"</span><span style="color: #800000;">class</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">form-control</span><span style="color: #800000;">"</span><span style="color: #000000;">}),

    }
    error_messages </span>= {  <span style="color: #008000;">#</span><span style="color: #008000;"> 设置每个字段的报错提示信息</span>
        <span style="color: #800000;">"</span><span style="color: #800000;">publisher</span><span style="color: #800000;">"</span><span style="color: #000000;">: {
            </span><span style="color: #800000;">"</span><span style="color: #800000;">required</span><span style="color: #800000;">"</span>: <span style="color: #800000;">"</span><span style="color: #800000;">必须给我选一个出版社!</span><span style="color: #800000;">"</span><span style="color: #000000;">
        },
        </span><span style="color: #800000;">"</span><span style="color: #800000;">authors</span><span style="color: #800000;">"</span><span style="color: #000000;">:{
            </span><span style="color: #800000;">"</span><span style="color: #800000;">required</span><span style="color: #800000;">"</span>:<span style="color: #800000;">"</span><span style="color: #800000;">必须选择一个作者</span><span style="color: #800000;">"</span><span style="color: #000000;">

        }
    }</span></pre>
复制代码
复制代码

2 views.py里面设置:

要先导入你刚才写的那个

from app01.forms import BookModelForm

添加

复制代码
复制代码
def add_book(request):
    form_obj = BookModelForm()
    if request.method == "POST":
        form_obj = BookModelForm(request.POST)
        if form_obj.is_valid():
            form_obj.save()
            return redirect("/book_list/")
    return render(request, "add_book.html", locals())
复制代码
复制代码

编辑

复制代码
复制代码
def edit_book(request, pk):
    book_obj = models.Book.objects.filter(id=pk).first()
    print("我是book_obj", book_obj)
    # instance实例
    form_obj = BookModelForm(instance=book_obj)  # 实例化的form_obj
    if request.method == "POST":
        # 获取用户提交过来的数据,用request.POST传过来的数据去更新book_obj这本书
        form_obj = BookModelForm(request.POST, instance=book_obj)
        if form_obj.is_valid():
            form_obj.save()
            return redirect("/book_list/")
    return render(request, "edit_book.html", locals())
复制代码
复制代码

3 html编辑和添加内容都是一样的

复制代码
复制代码
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>添加书籍</title>
 6     <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
 7 </head>
 8 <body>
 9 
10 <div class="container">
11     <div class="row">
12         <div class="col-md-8 col-md-offset-2">
13             <h1>添加书籍</h1>
14 
15             <form action="" method="post" novalidate autocomplete="off">
16                 {% csrf_token %}
17 
18                 {% for field in form_obj %}
19                     <div class="form-group">
20                         <label for="{{ field.id_for_label }}">{{ field.label }}</label>
21                         {{ field }}
22                         <p>{{ field.errors.0 }}</p>
23                     </div>
24                 {% endfor %}
25                 <input type="submit" class="btn btn-success">
26             </form>
27         </div>
28     </div>
29 </div>
30 
31 </body>
32 </html>
复制代码
复制代码

 

引用自[咳~](https://www.cnblogs.com/xu12135/p/9845598.html)
posted @ 2019-08-07 16:44  luowen罗文  阅读(419)  评论(0编辑  收藏  举报