_姜3

@form表单
form使用HTML5语法,顶部需添加说明

from .forms import NameForm
from django.core.mail import send_mail
if request.method == 'POST':
        # 接受request.POST参数构造form类的实例
        form = NameForm(request.POST)
        # 验证数据是否合法
        if form.is_valid():
            #form.cleaned_data字典中读取所有的表单数据
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            sender = form.cleaned_data['sender']
            cc_myself = form.cleaned_data['cc_myself']

            recipients = ['[email protected]']
            if cc_myself:
                    recipients.append(sender)

            send_mail(subject, message, sender, recipients)
            return HttpResponseRedirect('/thanks/')

from django import forms
class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

= = =

#template表单渲染格式
Django自动为每个input元素设置了一个id名称,对应label的for参数。
{{ form.as_p }}
{{ form.as_ul }}
{{ form.as_table }}

#手动渲染表单字段
{{ form.non_field_errors }}
{{ form.subject.errors }} #{{ form.subject.label_tag }} {{ form.subject }}
#渲染表单错误信息errorlist {% if form.subject.errors %}
    {% for error in form.subject.errors %}
  1. {{ error|escape }}
  2. {% endfor %}
{% endif %} #循环表单的字段 {% for field in form %}
{{ field.errors }} {{ field.label_tag }} {{ field }} {% if field.help_text %}

{{ field.help_text|safe }}

{% endif %}
{% endfor %} #不可见字段特殊处理hidden_fields()和visible_fields() {# 循环那些不可见的字段 #} {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %} {# 循环可见的字段 #} {% for field in form.visible_fields %}
{{ field.errors }} {{ field.label_tag }} {{ field }}
{% endfor %} #重用表单模板 include+with参数,给每个表单模板取个别名 {% include "form_snippet.html" with form=comment_form %} 使用{% for field in comment_form %} # 单独的表单模板文件form_snippet.html: {% for field in form %}
{{ field.errors }} {{ field.label_tag }} {{ field }}
{% endfor %}

= = =

1 表单的绑定属性
Form.is_bound True/False
f= ContactForm()#新建一个未绑定的表单
data={'name':anna,'age':12,'marriage':True}
f= ContactForm(date)#绑定了
即使data={}也算绑定

2 使用表单验证数据
Form.clean()
Form.is_valid()#验证数据是否合适的布尔值

3 Form.errors属性保存了错误信息字典
- f.errors
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
- Form.errors.as_data()返回一个字典,将字段映射到原始的ValidationError实例
{'sender': [ValidationError(['Enter a valid email address.'])],
'subject': [ValidationError(['This field is required.'])]}
- Form.errors.as_json(escape_html=False)返回序列化后的错误字典
{"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{"message": "This field is required.", "code": "required"}]}

4 Form.add_error(field, error)向特定字段添加错误信息

5 Form.has_error(field, code=None)判断某个字段是否有指定code错误,当code为None任何错误均返回True

6 Form.non_field_errors()返回Form.errors中不是与特定字段相关联的错误

7 Form.has_changed()表单是否发生了变化
f = ContactForm(data, initial=data)
f.has_changed()#表单是否发生了变化True、False

8 Form.changed_data返回有变化的字段的列表
f = ContactForm(request.POST, initial=data)#
if f.has_changed():
    print("The following fields changed: %s" % ", ".join(f.changed_data))

9 通过fileds属性访问表单的字段
for row in f.fields.values(): print(row)
f.fields['name']
f.as_table().split('\n')[0]#显示tr里的第一个
f.fields['name'].label = "Username"#修改name字段为Username

10 f.cleaned_data不仅负责验证数据还会将其转为正确的格式
cleaneddata只包含合法的字段,只包含Form定义的字段,data里没赋值的值是空
f.cleaned_data
{'nick_name': '', 'first_name': 'John', 'last_name': 'Lennon'}

11 如果表单是绑定的输出的html将包含数据data


###渲染
f = ContactForm()
f.as_table()
Form.as_p()
Form.as_url()
Form.as_table()

= = =

将上传的文件绑定到表单*处理带有FileField和ImageField字段
为了上传文件,你需要确保你的
元素定义enctype为"multipart/form-data": # 为表单绑定image字段 文件数据的处理与普通的表单数据是分开的,所以如果表单包含FileField和ImageField,绑定表单时你需要指定第二个参数 >>> from django.core.files.uploadedfile import SimpleUploadedFile >>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': '[email protected]', ... 'cc_myself': True} >>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', )} >>> f = ContactFormWithMugshot(data, file_data) 一般使用request.FILES作为文件数据的源: # Bound form with an image field, data from the request >>> f = ContactFormWithMugshot(request.POST, request.FILES)

核心字段
>>> from django import forms
>>> f = forms.CharField(required=False)
>>> f.clean('foo')
'foo'
>>> f.clean(' ')
' '
>>> f.clean(0)
'0'

label()添加人类友好提示,若无,则为该字段首字母大写
>>> class CommentForm(forms.Form):
...     name = forms.CharField(label='Your name')
...     url = forms.URLField(label='Your website', required=False)
...     comment = forms.CharField()
>>> f = CommentForm(auto_id=False)
>>> print(f)
Your name:
Your website:
Comment:
>>> print tf['name'].label_tag()#输出label
Your name:

label_suffixDjango默认为上面的label参数后面加个冒号后缀
>>> class ContactForm(forms.Form):
...     age = forms.IntegerField()
...     nationality = forms.CharField()
...     captcha_answer = forms.IntegerField(label='2 + 2', label_suffix=' =')#
>>> f = ContactForm(label_suffix='?')#
>>> print f.as_p() 

initial()给表单元素定义初始值*input元素的value参数的值 如data没有填值的话,initial的值不会作为“默认”的数据。initial值只用于原始表单的显示 >>> class CommentForm(forms.Form): ... name = forms.CharField(initial='Your name') ... url = forms.URLField(initial='http://') ... comment = forms.CharField() ... day = forms.DateField(initial=datetime.date.today)#传入一个可调用的对象 >>> f = CommentForm(auto_id=False) print f Name: Url: Comment: >>> data = {'name': '', 'url': '', 'comment': 'Foo'} >>> f = CommentForm(data) >>> f.is_valid() False # The form does *not* fall back to using the initial values. >>> f.errors {'url': ['This field is required.'], 'name': ['This field is required.']} ***widget 最重要的参数之一,指定渲染Widget时使用的widget类,也就是这个form字段在HTML页面中是显示为文本输入框?密码输入框?单选按钮?多选框?还是别的.... help_text该参数用于设置字段的辅助描述文本 subject = forms.CharField(max_length=100, help_text='100 characters max.') f = HelpTextContactForm(auto_id=False) print f.as_table() error_messages该参数允许你覆盖字段引发异常时的默认信息。 传递的是一个字典,其键为你想覆盖的错误信息 name = forms.CharField(error_messages={'required': 'Please enter your name'})#如果error是因为required导致的 validators指定一个列表,其中包含了为字段进行验证的函数 localize参数帮助实现表单数据输入的本地化 disabled设置有该属性的字段在前端页面中将显示为不可编辑状态 即使非法篡改了前端页面的属性,向服务器提交了该字段的值,也将依然被忽略 ***内置Field类型 |field|css|data| |:--|:-|:-| |BooleanField | CheckboxInput | required| |CharField max_length | TextInput | min_length strip empty_value required| |ChoiceField | Select | required invalid_choice| |TypedChoiceField | Select | required invalid_choice coerce empty_value| |DateField | DateInput | input_formats required invalid %Y-%m-%d| |DateTimeField | DateTimeInput | input_formats required invalid'%Y-%m-%d %H:%M:%S'| |DurationField | TextInput | min_length invalid required| |EmailField | EmailInput | min_length required invalid| |FileField | ClearableFileInput | missing, invalid, required, empty, max_length max_length allow_empty_file| |FilePathField | Select | required invalid_choice path recursive match allow_files allow_folders| |FloatField | NumberInput TextInput | max_value, invalid, required, min_value| |ImageField | ClearableFileInput | missing, invalid, required, empty, invalid_image pillow| |IntegerField | NumberInput TextInput | max_value, invalid, required, min_value| |GenericIPAddressField | TextInput | protocol unpack_ipv4| |MultipleChoiceField | SelectMultiple | invalid_list, invalid_choice, required| |TypedMultipleChoiceField | SelectMultiple | invalid_list, invalid_choice, required coerce empty_value| |NullBooleanField| |RegexField | TextInput | max_length,min_length和strip参数,类似CharField| |SlugField | TextInput | |TimeField | TextInput | '%H:%M:%S'| |URLField | UrlInput | |UUIDField | TextInput | |ComboField | |MultiValueField | |MultiValueField | |SplitDateTimeField | ***自定义字段 只需要创建一个django.forms.Field的子类,并实现clean()和__init__()构造方法。 __init__()构造方法需要接收前面提过的那些核心参数,比如widget、required,、label、help_text、initial。 还可以通过覆盖get_bound_field()方法来自定义访问字段的方式

= = =

###widget
@指定使用的widget
每个字段都有一个默认的widget类型。如果你想要使用一个不同的Widget,可以在定义字段时使用widget参数。 像这样:
from django import forms
class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField(widget=forms.Textarea)#覆盖原来的TextInput Widget

@widget添加css特殊属性
可以在创建Widget时使用Widget.attrs参数来实现这一目的:
class CommentForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
    url = forms.URLField()
    comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

@许多widget具有可选的额外参数,下面的示例中,设置了SelectDateWidget的years 属性,注意参数的传递方法:
from django import forms
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
FAVORITE_COLORS_CHOICES = (
    ('blue', 'Blue'),
    ('green', 'Green'),
    ('black', 'Black'),
)

class SimpleForm(forms.Form):
    birth_year = forms.DateField(widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES))
    favorite_colors = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple,
        choices=FAVORITE_COLORS_CHOICES,
    )

@Meta类内部的widgets属性
from django.forms import ModelForm, Textarea
from myapp.models import Author
class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        widgets = {
            'name': Textarea(attrs={'cols': 80, 'rows': 20}), # 改写name属性
        }

将fields属性的值设为__all__,表示将映射的模型中的全部字段都添加到表单类中来。
from django.forms import ModelForm
class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = '__all__'
exclude属性:
表示将model中,除了exclude属性中列出的字段之外的所有字段,添加到表单类中作为表单字段。
class PartialAuthorForm(ModelForm):
    class Meta:
        model = Author
        exclude = ['title']



你可能感兴趣的:(_姜3)