19-2 from和modelform的用法和介紹

一 formcss

1. form的做用html

  1. 生成HTML代碼
  2. 幫咱們作數據有效性的校驗
  3. 保留上次輸入內容,顯示錯誤提示數據庫

2. form組件校驗數據有效性
  1. 內置的校驗規則
  1. require=True 該字段必填
  2. max_length 該字段的最大長度
  3. min_length 該字段的最小長度django

 

 2. 自定義校驗規則
  1. 如手機號的格式 利用內置的正則校驗器
  from django.core.validators import RegexValidator
  validators=[RegexValidator(r'^1[356789]\d{9}$', "手機號碼格式不正確")],bootstrap

 


3. 使用鉤子函數作校驗
 1. 局部鉤子(hook)
           在form類內部定義一個 clean_字段名() 方法app

 例子ide

  #自定義一個局部鉤子函數含有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標籤設置默認值post

  1. 每個字段設置默認值
  initial="默認值"
ui

實例:關於使用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)

            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()
    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=BookForm(book_dict)
    if request.method=="POST":
        form_obj=BookForm(request.POST) # 接受用戶傳來的數據
        if form_obj.is_valid(): # 判斷數據是否正常
            book_obj.title=form_obj.cleaned_data.get("title")
            book_obj.publisher_id=form_obj.cleaned_data.get("publisher_date")
            book_obj.publisher_id=form_obj.cleaned_data.get("publisher")
            book_obj.save()
            book_obj.authors.set(form_obj.cleaned_data.get("authors"))
            return redirect("/book_list")
    return render(request,"edit_book.html",locals())

 

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={ # 設置每一個字段的插件信息
            "title": forms.widgets.TextInput(attrs={"class": "form-control"}),
            "phone": forms.widgets.TextInput(attrs={"class": "form-control"}),
            "publisher": forms.widgets.Select(attrs={"class": "form-control"}),
            "authors": forms.widgets.SelectMultiple(attrs={"class": "form-control"}),

        }
        error_messages = {  # 設置每一個字段的報錯提示信息
            "publisher": {
                "required": "必須給我選一個出版社!"
            },
            "authors":{
                "required":"必須選擇一個做者"

            }
        }

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>
View Code
相關文章
相關標籤/搜索