Django(十五)Form組件

參考博客:html

http://www.javashuo.com/article/p-vuqaekra-ma.htmlpython

 http://www.cnblogs.com/wupeiqi/articles/6144178.htmlgit

Form組件

    - 對用戶請求的驗證
        - AJax
        - Form
    - 生成HTML代碼

    a. 建立一個類
    b. 類中建立字段(包含正則表達式)
    c. GET
        obj = Fr()
        obj.user = > 自動生成HTML
        
    d. POST
        obj = Fr(request.POST)
        if obj.is_valid():
            obj.cleaned_data
        else:
            obj.errors
            return .... obj

 

1、Form組件介紹

Form組件能夠作的幾件事情:正則表達式

  一、用戶請求數據驗證數據庫

  二、自動生成錯誤信息    django

  三、打包用戶提交的正確信息瀏覽器

  四、若是其中有一個錯誤了,其餘的正確這,保留上次輸入的內容app

  五、生成HTML標籤dom

2、Form組件的使用

  一、建立規則ide

class Foo(Form): #必須繼承
    username = xxx
    password = xxx
    email = xxx
注意這裏的字段必須和input的name字段一致

  二、數據和規則進行匹配

先導入view.py

from django.forms import Form
from django.forms import fields
from django.forms import widgets
from django.shortcuts import render,redirect
from app01 import models
# Create your views here.
from django.forms import Form
from django.forms import fields
from django.forms import widgets
# 一、建立規則
class TeacherForm(Form):  #必須繼承Form
    # 建立字段,本質上是正則表達式
    username = fields.CharField(
        required=True,     #必填字段
        error_messages={"required":"用戶名不能爲空!!"},  #顯示中文錯誤提示
        widget=widgets.TextInput(attrs={"placeholder":"用戶名","class":"form-control"})  #自動生成input框
       )
    password = fields.CharField(required=True, error_messages={'required': '密碼不能爲空'},
                                widget=widgets.TextInput(attrs={'placeholder': '密碼', 'class': 'form-control'}))  # 不能爲空
    email = fields.EmailField(
        required=True,
        error_messages={"required":"郵箱不能爲空!!","invalid":"無效的郵箱"},
        widget=widgets.EmailInput(attrs={"placeholder": "郵箱", "class": "form-control"})  # 自動生成input框
    ) #不能爲空且郵箱格式要一致

# 二、使用規則:將數據和規則進行匹配
def teacherindex(request):
    teacher_obj = models.UserInfo.objects.all()
    # print(teacher_obj)
    return render(request,"teacherindex.html",{"teacher_obj":teacher_obj})
def add(request):
    if request.method=="GET":
        form = TeacherForm()  #只是讓顯示一個input框
        return render(request,"add.html",{"form":form })
    else:
        form = TeacherForm(data=request.POST)
        # print(form)  #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
        if form.is_valid():# 開始驗證
            # print('執行成功',form.cleaned_data)          # 全部匹配成功,字典
            # {'username': 'asd', 'password': 'sdf', 'email': 'sadf@live.com','ut_id':1}
            form.cleaned_data['ut_id'] = 1  #要分的清是班主任仍是講師
            models.UserInfo.objects.all().create(**form.cleaned_data)
            return redirect("/teacherindex/")
        else:
            # print("=====?",form.errors,type(form.errors))#返回失敗的結果
            # print(form.errors["username"][0])   #拿到返回失敗的結果,渲染到頁面
            return render(request,"add.html",{"form":form})

html

{% block right %}
    <h1>添加老師信息</h1>
    <hr>
    <form method="post" novalidate>
        {% csrf_token %}
        <p>姓名:{{ form.username }}</p>{{ form.errors.username.0 }}
        <p>密碼:{{ form.password }}</p>{{ form.errors.password.0 }}
        <p>郵箱:{{ form.email }}</p>{{ form.errors.email.0 }}
        <p><input type="submit" value="提交"></p>
    </form>
{% endblock %}

若是訪問視圖的是一個GET 請求,它將建立一個空的表單實例並將它放置到要渲染的模板的上下文中。這是咱們在第一個訪問該URL 時預期發生的狀況。

若是表單的提交使用POST 請求,那麼視圖將再次建立一個表單實例並使用請求中的數據填充它:form = NameForm(request.POST)。這叫作」綁定數據至表單「(它如今是一個綁定的表單)。

咱們調用表單的is_valid()方法;若是它不爲True,咱們將帶着這個表單返回到模板。這時表單再也不爲空(未綁定),因此HTML 表單將用以前提交的數據填充,而後能夠根據要求編輯並改正它。

若是is_valid()True,咱們將可以在cleaned_data 屬性中找到全部合法的表單數據。在發送HTTP 重定向給瀏覽器告訴它下一步的去向以前,咱們能夠用這個數據來更新數據庫或者作其它處理。

注意: form = TeacherForm()  #沒有參數,只是一個input框

    form = TeacherForm(data=request.POST) # 數據和規則放置一塊兒 (添加的時候用)

    form = TeacherForm(initial={'username':obj.username,'password':obj.password,'email':obj.email})   # 顯示input,而且將數據庫中的默認值填寫到input框中 (編輯的時候用)

 

簡單實例(一)

class F1Form(forms.Form):
    user = fields.CharField(required=True,
                            max_length=18,
                            min_length=6,
                            error_messages={'required':'用戶名不能爲空','max_length': '太長了',
                                            'min_length':'過短了'},
                            widget=widgets.TextInput(attrs={'placeholder':"用戶名"})
                            )
    pwd = fields.CharField(required=True, min_length=9, error_messages={'min_length': "過短了"})
    age = fields.IntegerField(required=True)
    email = fields.EmailField(required=True,min_length=8, error_messages={'invalid': "格式錯誤"})

def f1(request):
    if request.method == 'GET':
        obj = F1Form()
        return render(request, 'f1.html', {'obj': obj})
    if request.method == "POST":
        obj = F1Form(request.POST)
        if obj.is_valid():
            print("驗證成功", obj.cleaned_data)
            return redirect('http://www.xiaohuar.com')
        else:
            print("驗證失敗", obj.errors)
            return render(request, 'f1.html', {"obj": obj})
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/f1/" method="post" novalidate>
    {% csrf_token %}
    <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>
    <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
    <p>{{ obj.age }}{{ obj.errors.age.0 }}</p>
    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
    <input type="submit" value="提交">
</form>
</body>
</html>
html

簡單實例(二)

"""django_form URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/', views.users),
    path('add_user/', views.add_user),
    re_path(r'edit_user-(\d+)/', views.edit_user),
]
urls.py
from django.shortcuts import render, redirect
from app01 import models
from app01 import forms
# Create your views here.

def users(request):
    obj_list = models.UserInfo.objects.all()
    return render(request, "user.html", {"obj_list": obj_list})

def add_user(request):
    if request.method == "GET":
        obj = forms.UserForm()
        return render(request, "add_user.html", {"obj": obj})
    if request.method == "POST":
        obj = forms.UserForm(request.POST)
        if obj.is_valid():
            models.UserInfo.objects.create(**obj.cleaned_data)
            return redirect("/users/")
        else:
            return render(request, "add_user.html", {"obj": obj})

def edit_user(request,nid):
    if request.method == "GET":
        data = models.UserInfo.objects.filter(id=nid).first()
        obj = forms.UserForm({'username': data.username,'email': data.email})
        return render(request, "edit_user.html", {'obj': obj, 'nid': nid})
    else:
        obj = forms.UserForm(request.POST)
        if obj.is_valid():
            models.UserInfo.objects.filter(id=nid).update(**obj.cleaned_data)
            return redirect("/users/")
        else:
            return render(request, 'edit_user.html', {'obj': obj, 'nid': nid})
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<a href="/add_user/">添加</a>

{% for item in obj_list %}
    <li>
        {{ item.id }}--{{ item.username }}--{{ item.email }}
        <a href="/edit_user-{{ item.id }}/">編輯</a>
    </li>
{% endfor %}

</body>
</html>
users.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/add_user/" method="post" novalidate>
    {% csrf_token %}
    <p>{{ obj.username }}{{ obj.errors.username.0 }}</p>
    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
    <input type="submit" value="提交">
</form>

</body>
</html>
add_user.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/edit_user-{{ nid }}/" method="post" novalidate>
        {% csrf_token %}
        <p>{{ obj.username }}{{ obj.errors.username.0 }}</p>
        <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
        <input type="submit" value="提交">
    </form>
</body>
</html>
edit.html
from django import forms as dforms
from django.forms import fields

class UserForm(dforms.Form):
    username = fields.CharField()
    email = fields.EmailField()
forms.py

 

Widgets

每一個表單字段都有一個對應的Widget 類,它對應一個HTML 表單Widget,例如<input type="text">

在大部分狀況下,字段都具備一個合理的默認Widget。例如,默認狀況下,CharField 具備一個TextInput Widget,它在HTML 中生成一個<input type="text">

字段的數據

無論表單提交的是什麼數據,一旦經過調用is_valid() 成功驗證(is_valid() 返回True),驗證後的表單數據將位於form.cleaned_data 字典中。這些數據已經爲你轉換好爲Python 的類型。

注:此時,你依然能夠從request.POST 中直接訪問到未驗證的數據,可是訪問驗證後的數據更好一些。

在上面的聯繫表單示例中,is_married將是一個布爾值。相似地,IntegerField 和FloatField 字段分別將值轉換爲Python 的int 和float

 

實例:

from django.forms import Form
from django.forms import widgets
from django.forms import fields
 
class MyForm(Form):
    user = fields.CharField(
        widget=widgets.TextInput(attrs={'id': 'i1', 'class': 'c1'})
    )
 
    gender = fields.ChoiceField(
        choices=((1, ''), (2, ''),),
        initial=2,
        widget=widgets.RadioSelect
    )
 
    city = fields.CharField(
        initial=2,
        widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
    )
 
    pwd = fields.CharField(
        widget=widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
    )
建立form類
from django.shortcuts import render, redirect
from .forms import MyForm
 
 
def index(request):
    if request.method == "GET":
        obj = MyForm()
        return render(request, 'index.html', {'form': obj})
    elif request.method == "POST":
        obj = MyForm(request.POST, request.FILES)
        if obj.is_valid():
            values = obj.clean()
            print(values)
        else:
            errors = obj.errors
            print(errors)
        return render(request, 'index.html', {'form': obj})
    else:
        return redirect('http://www.google.com')
views函數處理
<form action="/" method="POST" enctype="multipart/form-data">
    <p>{{ form.user }} {{ form.user.errors }}</p>
    <p>{{ form.gender }} {{ form.gender.errors }}</p>
    <p>{{ form.city }} {{ form.city.errors }}</p>
    <p>{{ form.pwd }} {{ form.pwd.errors }}</p>
    <input type="submit"/>
</form>
生成HTML

 

        obj = forms.MyForm()
        txt = "<input type='text'/>"
        from django.utils.safestring import mark_safe
        txt = mark_safe(txt)
        return render(request, "index.html", {'obj': obj, 'txt':txt})

#或者在html文件加{{ txt|safe }},使用以上方式不須要再加'|safe'

 

 

Form類

建立Form類時,主要涉及到 【字段】 和 【插件】,字段用於對用戶請求數據的驗證,插件用於自動生成HTML;

一、Django內置字段以下:

  1 Field
  2     required=True,               是否容許爲空
  3     widget=None,                 HTML插件
  4     label=None,                  用於生成Label標籤或顯示內容
  5     initial=None,                初始值
  6     help_text='',                幫助信息(在標籤旁邊顯示)
  7     error_messages=None,         錯誤信息 {'required': '不能爲空', 'invalid': '格式錯誤'}
  8     show_hidden_initial=False,   是否在當前插件後面再加一個隱藏的且具備默認值的插件(可用於檢驗兩次輸入是否一直)
  9     validators=[],               自定義驗證規則
 10     localize=False,              是否支持本地化
 11     disabled=False,              是否能夠編輯
 12     label_suffix=None            Label內容後綴
 13  
 14  
 15 CharField(Field)
 16     max_length=None,             最大長度
 17     min_length=None,             最小長度
 18     strip=True                   是否移除用戶輸入空白
 19  
 20 IntegerField(Field)
 21     max_value=None,              最大值
 22     min_value=None,              最小值
 23  
 24 FloatField(IntegerField)
 25     ...
 26  
 27 DecimalField(IntegerField)
 28     max_value=None,              最大值
 29     min_value=None,              最小值
 30     max_digits=None,             總長度
 31     decimal_places=None,         小數位長度
 32  
 33 BaseTemporalField(Field)
 34     input_formats=None          時間格式化   
 35  
 36 DateField(BaseTemporalField)    格式:2015-09-01
 37 TimeField(BaseTemporalField)    格式:11:12
 38 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 39  
 40 DurationField(Field)            時間間隔:%d %H:%M:%S.%f
 41     ...
 42  
 43 RegexField(CharField)
 44     regex,                      自定製正則表達式
 45     max_length=None,            最大長度
 46     min_length=None,            最小長度
 47     error_message=None,         忽略,錯誤信息使用 error_messages={'invalid': '...'}
 48  
 49 EmailField(CharField)      
 50     ...
 51  
 52 FileField(Field)
 53     allow_empty_file=False     是否容許空文件
 54  
 55 ImageField(FileField)      
 56     ...
 57     注:須要PIL模塊,pip3 install Pillow
 58     以上兩個字典使用時,須要注意兩點:
 59         - form表單中 enctype="multipart/form-data"
 60         - view函數中 obj = MyForm(request.POST, request.FILES)
 61  
 62 URLField(Field)
 63     ...
 64  
 65  
 66 BooleanField(Field)  
 67     ...
 68  
 69 NullBooleanField(BooleanField)
 70     ...
 71  
 72 ChoiceField(Field)
 73     ...
 74     choices=(),                選項,如:choices = ((0,'上海'),(1,'北京'),)
 75     required=True,             是否必填
 76     widget=None,               插件,默認select插件
 77     label=None,                Label內容
 78     initial=None,              初始值
 79     help_text='',              幫助提示
 80  
 81  
 82 ModelChoiceField(ChoiceField)
 83     ...                        django.forms.models.ModelChoiceField
 84     queryset,                  # 查詢數據庫中的數據
 85     empty_label="---------",   # 默認空顯示內容
 86     to_field_name=None,        # HTML中value的值對應的字段
 87     limit_choices_to=None      # ModelForm中對queryset二次篩選
 88      
 89 ModelMultipleChoiceField(ModelChoiceField)
 90     ...                        django.forms.models.ModelMultipleChoiceField
 91  
 92  
 93      
 94 TypedChoiceField(ChoiceField)
 95     coerce = lambda val: val   對選中的值進行一次轉換
 96     empty_value= ''            空值的默認值
 97  
 98 MultipleChoiceField(ChoiceField)
 99     ...
100  
101 TypedMultipleChoiceField(MultipleChoiceField)
102     coerce = lambda val: val   對選中的每個值進行一次轉換
103     empty_value= ''            空值的默認值
104  
105 ComboField(Field)
106     fields=()                  使用多個驗證,以下:即驗證最大長度20,又驗證郵箱格式
107                                fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
108  
109 MultiValueField(Field)
110     PS: 抽象類,子類中能夠實現聚合多個字典去匹配一個值,要配合MultiWidget使用
111  
112 SplitDateTimeField(MultiValueField)
113     input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
114     input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
115  
116 FilePathField(ChoiceField)     文件選項,目錄下文件顯示在頁面中
117     path,                      文件夾路徑
118     match=None,                正則匹配
119     recursive=False,           遞歸下面的文件夾
120     allow_files=True,          容許文件
121     allow_folders=False,       容許文件夾
122     required=True,
123     widget=None,
124     label=None,
125     initial=None,
126     help_text=''
127  
128 GenericIPAddressField
129     protocol='both',           both,ipv4,ipv6支持的IP格式
130     unpack_ipv4=False          解析ipv4地址,若是是::ffff:192.0.2.1時候,可解析爲192.0.2.1, PS:protocol必須爲both才能啓用
131  
132 SlugField(CharField)           數字,字母,下劃線,減號(連字符)
133     ...
134  
135 UUIDField(CharField)           uuid類型
136     ...

注:UUID是根據MAC以及當前時間等建立的不重複的隨機字符串

>>> import uuid

    # make a UUID based on the host ID and current time
    >>> uuid.uuid1()    # doctest: +SKIP
    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

    # make a UUID using an MD5 hash of a namespace UUID and a name
    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

    # make a random UUID
    >>> uuid.uuid4()    # doctest: +SKIP
    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

    # make a UUID using a SHA-1 hash of a namespace UUID and a name
    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

    # make a UUID from a string of hex digits (braces and hyphens ignored)
    >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

    # convert a UUID to a string of hex digits in standard form
    >>> str(x)
    '00010203-0405-0607-0809-0a0b0c0d0e0f'

    # get the raw 16 bytes of the UUID
    >>> x.bytes
    b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

    # make a UUID from a 16-byte string
    >>> uuid.UUID(bytes=x.bytes)
    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
UUID

 

二、Django內置插件:

# 單radio,值爲字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
# )
 
# 單radio,值爲字符串
# user = fields.ChoiceField(
#     choices=((1, '上海'), (2, '北京'),),
#     initial=2,
#     widget=widgets.RadioSelect
# )
 
# 單select,值爲字符串
# user = fields.CharField(
#     initial=2,
#     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
# )
 
# 單select,值爲字符串
# user = fields.ChoiceField(
#     choices=((1, '上海'), (2, '北京'),),
#     initial=2,
#     widget=widgets.Select
# )
 
# 多選select,值爲列表
# user = fields.MultipleChoiceField(
#     choices=((1,'上海'),(2,'北京'),),
#     initial=[1,],
#     widget=widgets.SelectMultiple
# )
 
 
# 單checkbox
# user = fields.CharField(
#     widget=widgets.CheckboxInput()
# )
 
 
# 多選checkbox,值爲列表
# user = fields.MultipleChoiceField(
#     initial=[2, ],
#     choices=((1, '上海'), (2, '北京'),),
#     widget=widgets.CheckboxSelectMultiple
# )

注意:

在使用選擇標籤時,須要注意choices的選項能夠從數據庫中獲取,可是因爲是靜態字段 ***獲取的值沒法實時更新***,那麼須要自定義構造方法從而達到此目的。

方式一:

from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
 
class MyForm(Form):
 
    user = fields.ChoiceField(
        # choices=((1, '上海'), (2, '北京'),),
        initial=2,
        widget=widgets.Select
    )
 
    def __init__(self, *args, **kwargs):
        super(MyForm,self).__init__(*args, **kwargs)
        # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)
        #
        self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption')

self.fields語句必定要在調用父類構造函數以後,由於調用父類構造函數以後纔有字段fields

方式二:

使用django提供的ModelChoiceField和ModelMultipleChoiceField字段來實現

from django import forms
from django.forms import fields
from django.forms import widgets
from django.forms import models as form_model
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
 
class FInfo(forms.Form):
    authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())
    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

 

Form重點:
    - 字段
        用於保存正則表達式
        ChoiceField *****
        MultipleChoiceField
        CharField
        IntegerField
        DecimalField
        DateField
        DateTimeField
        EmailField
        GenericIPAddressField
        FileField
        
        RegexField

 

 

實例

from django.shortcuts import render
from django import forms
from django.forms import fields
from django.forms import widgets
class TestForm(forms.Form):
    user = fields.CharField(
        required=True, # 是否必填
        max_length=12, # 最大長度
        min_length=3,  # 最小長度
        error_messages={}, # 錯誤提示
        #widget = widgets.Select(), # 定製HTML插件
        label='用戶名',
        initial='請輸入用戶',
        help_text='asdfasdf',
        show_hidden_initial=False,
        # validators=[]
        disabled=True,
        label_suffix='->' # obj.as_p 會顯示出來
    )
    age = fields.IntegerField(
        label='年齡',
        max_value= 12,
        min_value=5,
        error_messages={
            'max_value':'太大了'
        }
    )

    email = fields.EmailField(
        label='郵箱'
    )

    img = fields.FileField()

    city = fields.TypedChoiceField(
        coerce=lambda x: int(x),
        choices=[(1,'上海',),(2,'北京'),(3,'沙河'),],
        initial=2
    )
    bobby = fields.MultipleChoiceField(
        choices=[(1,'剛娘'),(2,'鐵娘'),(3,'鋼彈')],
        initial=[1,2]
    )

    xoo = fields.FilePathField(
        path='app01'
    )

def test(request):
    if request.method == 'GET':
        #obj = TestForm({'city':3})
        obj = TestForm()
        return render(request,'test.html',{'obj':obj})
    else:
        obj = TestForm(request.POST,request.FILES)
        obj.is_valid()
        print(obj.cleaned_data)
        return render(request, 'test.html', {'obj': obj})
views
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="POST" action="/test/" novalidate enctype="multipart/form-data">

        {% csrf_token %}
        <p>{{ obj.user.label }}{{ obj.user }}</p>
        <p>{{ obj.age.label }}{{ obj.age }}{{ obj.errors.age.0 }}</p>
        <p>{{ obj.email.label }}{{ obj.email }}</p>
        <p>{{ obj.img.label }}{{ obj.img }}</p>
        <p>{{ obj.city.label }}{{ obj.city }}</p>
        <p>{{ obj.bobby.label }}{{ obj.bobby }}</p>
        <p>{{ obj.xoo.label }}{{ obj.xoo }}</p>
        <input  type="submit" value="提交"/>
    </form>
</body>
</html>
html

 

ModelChoiceField

特殊的單選或多選時,數據源是否能實時更新?

 

ModelChoiceField獲取的值能夠實時更新

from app01 import models
from django.forms.models import ModelChoiceField
class LoveForm(forms.Form):
    price = fields.IntegerField()
    user_id = fields.IntegerField(
        # widget=widgets.Select(choices=[(0,'alex'),(1,'劉皓宸'),(2,'楊建'),])
        widget=widgets.Select()
    )

    user_id2 = ModelChoiceField(
        queryset=models.UserInfo.objects.all(),
        to_field_name='id'
    )

    def __init__(self,*args,**kwargs):
        # 拷貝全部的靜態字段,複製給self.fields
        super(LoveForm,self).__init__(*args,**kwargs)
        self.fields['user_id'].widget.choices = models.UserInfo.objects.values_list('id', 'username')


def love(request):
    obj = LoveForm()
    return render(request,'love.html',{'obj':obj})
Views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>價格:{{ obj.price }}</p>
    <p>姓名:{{ obj.user_id }}</p>
    <p>姓名:{{ obj.user_id2 }}</p>
</body>
</html>
html

 注意:依賴models中的str方法

相關文章
相關標籤/搜索