• Django(十五)Form组件


    参考博客:

    https://www.cnblogs.com/haiyan123/p/7778888.html

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

    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

    一、Form组件介绍

    Form组件可以做的几件事情:

      1、用户请求数据验证

      2、自动生成错误信息    

      3、打包用户提交的正确信息

      4、如果其中有一个错误了,其他的正确这,保留上次输入的内容

      5、生成HTML标签

    二、Form组件的使用

      1、创建规则

    class Foo(Form): #必须继承
        username = xxx
        password = xxx
        email = xxx
    注意这里的字段必须和input的name字段一致

      2、数据和规则进行匹配

    先导入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
    # 1、创建规则
    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框
        ) #不能为空且邮箱格式要一致
    
    # 2、使用规则:将数据和规则进行匹配
    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;

    1、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'x00x01x02x03x04x05x06x07x08	
    x0bx0c
    x0ex0f'
    
        # make a UUID from a 16-byte string
        >>> uuid.UUID(bytes=x.bytes)
        UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
    UUID

    2、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方法

  • 相关阅读:
    如何让touchmove之后不触发touchend的事件
    解决alert在ios版微信中显示url的问题(重写alert)
    meta常用标签总结
    HTTP状态码
    前端用到的一些功能
    判断鼠标从哪个方向进入--jQuery
    jsonp是什么
    数据结构与算法之链表-javascript实现
    数据结构之栈-JavaScript实现栈的功能
    数据结构之列表-javascript实现
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10670522.html
Copyright © 2020-2023  润新知