• django1.8forms读书笔记


    一、HttpRequest对象的一些属性或方法

    • request.path,The full path, not including the domain but including the leading slash,例如:"/hello/"
    • request.get_host(),The host (i.e., the “domain,” in common parlance).例如:"127.0.0.1:8000" or"www.example.com"
    • request.get_full_path(),The path, plus a query string (if available),例如:"/hello/?print=true"
    • request.is_secure(),True if the request was made via HTTPS. Otherwise, False。例如:True or False

    关于请求的其他信息request.META是一个字典,包含了所有HTTP头部信息,一些常见的keys如下:

    • HTTP_REFERER – The referring URL, if any. (Note the misspelling of REFERER.)
    • HTTP_USER_AGENT – The user’s browser’s user-agent string, if any. This looks something like:"Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17".
    • REMOTE_ADDR – The IP address of the client, e.g., "12.345.67.89". (If the request has passed through any proxies, then this might be a comma-separated list of IP addresses, e.g., "12.345.67.89,23.456.78.90".)

    注意:当不知道字典中是否含有一个键时,最好用get方法,因为META是一个字典,获取一个不存在的键会返回一个异常。例如:

    ua = request.META.get('HTTP_USER_AGENT', 'unknown')

    request.GET和request.POST是两个类似于字典的对象,他们都有get()keys() and values() 方法,也可以迭代for key in request.GET,

    POST数据基本上是都是来自于表单提交的数据,GET可以是表单也可以是网页的URL

    2、根据学生ID搜索学生信息的简单例子:

    models是

    class StudentInfo(models.Model):
        
        name = models.CharField(max_length = 50,default="");
        studentID = models.CharField(max_length=12,default="");
        sex = models.CharField(max_length = 5,default="");
        age = models.IntegerField(default=0);
        address = models.TextField(default="");
    View Code

    template文件夹里存放template文件,searchBase.html文件如下:

    <!DOCTYPE html>
    <html>
    <head>
        <title>
        {% block title %}{% endblock %}
        </title>
    </head>
    
    <body>
        <div>
        {% block search %}
        
        {% endblock %}    
        </div>
        <hr/>
        <div>
        {% block footer %}
            <p>©2016&nbsp;Allen&nbsp;</p>
        {% endblock %}    
        </div>
    </body>
    </html>
    View Code

    searchStudentInfo.html文件内容如下:

     1 {% extends "searchBase.html" %}
     2 
     3 {% block title %}get student infomation{% endblock %}
     4 
     5 {% block search %}
     6 <h1 style="text-align:center;">根据ID搜索学生信息</h1>
     7 <div>
     8     <form action="/student/search/" method="post" style="text-align:center;">
     9         <input type="text" name="q">
    10         <input type="submit" value="搜索">
    11     </form>
    12 </div>
    13 {% endblock %}    
    View Code

    在视图文件中定义搜索id的视图,SearchForm函数

    1 def SearchForm(request):
    2     return render(request, "searchStudentInfo.html")
    View Code

    在urls文件中定义路由

    url(r'^searchform/$', views.SearchForm),

    此时还不能正常工作,因为没有写搜索的响应函数。当然可以看一下效果

    接下来为其添加响应函数,views.py

    1 def SearchStudentInfo(request):
    2     if 'q' in  request.POST:
    3         searchInfo = "you searched %s"%request.POST['q'];
    4     else:
    5         searchInfo = "you submitted an empty form"
    6     return HttpResponse(searchInfo);
    View Code

    添加路由

    url(r'^search/$', views.SearchStudentInfo),

    此时可以正常工作。

    3、将查询结果做成模版进行显示

    创建显示结果模版searchResult.html代码如下:

     1 {% extends "searchBase.html"%}
     2 
     3 {% block title %}search result{% endblock %}
     4 
     5 {% block search %}
     6     <p>You searched for: <strong>{{ query }}</strong></p>
     7     {% if students %}
     8         <p>Found {{students|length}} students</p>
     9         <table>
    10             <tr>                
    11                 <td>姓名</td>
    12                 <td>学号</td>
    13                 <td>性别</td>
    14                 <td>年龄</td>
    15                 <td>地址</td>
    16             </tr>
    17             {% for student in students %}
    18             <tr>
    19                 
    20                 <td>{{ student.name }}</td>
    21                 <td>{{ student.studentID }}</td>
    22                 <td>{{ student.sex }}</td>
    23                 <td>{{ student.age }}</td>
    24                 <td>{{ student.address }}</td>
    25                 
    26             </tr>
    27             {% endfor %}
    28         </table>
    29     {% else %}
    30         <p>not found student where studentID = {{ query }}</p>
    31     {% endif %}
    32 {% endblock %}
    View Code

    修改视图函数views.py

     1 def SearchStudentInfo(request):
     2     if 'q' in  request.GET and request.GET['q']:
     3         stu =  StudentInfo.objects.filter(studentID=request.GET['q'])
     4         if stu:
     5             context = {'query':request.GET['q'],'students':stu}
     6             return render(request, 'searchResult.html', context)
     7         else:
     8             return HttpResponse("not found information");
     9         
    10     else:
    11         searchInfo = "you submitted an empty form"
    12     return HttpResponse(searchInfo);
    View Code

    此时可以运行一下查看结果,效果如下:

    二、对这个表单进行改进

    对网址http://127.0.0.1:8888/student/search/进行访问,有三种可能情况

    • 访问页面,此时没有‘q’参数在GET中
    • 点击提交按钮,‘q’在GET中,但是搜索框中没有搜索内容。
    • 点击提交按钮,‘q’在GET中,搜索框中有搜索内容。

    对于第一种情况我们不应该显示出错误信息,第二种情况应该显示出错信息,第三种情况应当进入数据库进行查询。为了更专业一点,当没有输入数据提交时,应当返回上一个查询框,而不是返回一个字符串。

    需要修改的地方有 1、视图函数  2、在搜索模版中加入判断的变量error

    views.py

     1 def SearchStudentInfo(request):
     2     error = False;
     3     if 'q' in  request.GET :
     4         if not request.GET['q']:
     5             error=True;
     6         else:
     7             stu =  StudentInfo.objects.filter(studentID=request.GET['q'])
     8             context = {'query':request.GET['q'],'students':stu}
     9             return render(request, 'searchResult.html', context)
    10     
    11     return render(request, 'searchStudentInfo.html', {'error':error});
    View Code

    searchStudentInfo.html

     1 {% extends "searchBase.html" %}
     2 
     3 {% block title %}search student infomation{% endblock %}
     4 
     5 {% block search %}
     6 <h1 style="text-align:center;">根据ID搜索学生信息</h1>
     7 <div>
     8     {% if error %}
     9         <p style="color: red;">Please submit a search term.</p>
    10     {% endif %}
    11     <form action="/student/search/" method="get" style="text-align:center;">
    12         学号:<input type="text" name="q">
    13         <input type="submit" value="搜索">
    14     </form>
    15 </div>
    16 {% endblock %}
    View Code

    2、

    <form action="" method="get">
    当 action=""表示提交表单时,将向当前的url提交。

    3、当表单是通过post提交过后,最好在处理过提交上来的数据后使用HttpResponseRedirect,以防止产生一些麻烦,比如:多次提交、刷新提交。可能会在后台数据库中产生多个相同记录。

    from django.http import HttpResponseRedirect

    三、form类,是django带来的处理form的一些类库,可以放在任意位置,不过一般将其单独成一个文件forms.py,和views.py放在同一个文件夹

    首先写一个forms.py文件,ContactForm类。

    from django import forms
    class ContactForm(forms.Form):
        subject = forms.CharField();
        email = forms.EmailField(required = False);
        message = forms.CharField();
    View Code

    注意:默认情况下form类的数据是必须的,可以通过参数来修改。required=False

    form类对象含有一些方法,比如:as_ul(),将每项数据li列出来,as_p():将每项数据生成段落。

    from studentInfo.forms import ContactForm
    c=ContactForm()
    print c.as_ul()
    <li><label for="id_subject">Subject:</label> <input type="text" name="subject" id="id_subject" /></li>
    <li><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></li>
    <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
    >>> print c.as_p()
    <p><label for="id_subject">Subject:</label> <input type="text" name="subject" id="id_subject" /></p>
    <p><label for="id_email">Email:</label> <input type="text" name="email" id="id_email" /></p>
    <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
    View Code

    也可以显示某一列

    >>> print c['subject']
    <input type="text" name="subject" id="id_subject" />
    >>> print c['message']
    <input type="text" name="message" id="id_message" />

    2、检查有效性,通过一个字典将forms类初始化。对象一旦初始化数据后,就是一个“bound”form。

    f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
    f.is_bound
    True

    检查有效性的函数是is_valid().如果数据有效,可以通过clean()方法,返回一个没有错误的数据字典。

    >>> f = ContactForm({'subject': 'Hello', 'message': 'Nice site!'})
    >>> f.is_valid()
    True
    >>> f = ContactForm({'subject': 'Hello', 'message': ''})
    >>> f.is_valid()
    False
    View Code

    也可以获得指定域的错误信息,通过errors属性。如果有错,则会显示出来;如果没有,则是一个空的列表。

    >>> f = ContactForm({'subject': 'Hello', 'message': ''})
    >>> f['message'].errors
    [u'This field is required.']
    >>> f['subject'].errors
    []
    >>> f['email'].errors
    []
    View Code

    每一个绑定数据的对象都有一个errors属性,是一个将域和错误信息列表映射起来。

    如果form对象的数据是有效的,则可以使用cleaned_data属性。他会将form对象转换成合适的python数据类型

    >>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
    >>> f.is_valid()
    True
    >>> f.cleaned_data
    {'message': u'Nice site!', 'email': u'adrian@example.com', 'subject': u'Hello'}
    3、在views文件中使用forms对象,例子如下:
    def ContactUs(request):
        if request.method =="POST":
            form = ContactForm(request.POST)
            if form.is_valid():
                cd = form.cleaned_data;
                print cd['subject'],cd['message'],cd.get('email', 'noreply@example.com')
                return HttpResponseRedirect('/student/contact/thanks/')
            
        else:
            form = ContactForm();
            
        return render(request, "contactus.html", {'form':form})
    View Code

    contactus.html模版文件如下:

    <html>
    <head>
        <title>Contact us</title>
    </head>
    <body>
        <h1>Contact us</h1>
    
        {% if form.errors %}
            <p style="color: red;">
                Please correct the error{{ form.errors|pluralize }} below.
            </p>
        {% endif %}
    
        <form action="" method="post">
            <table>
                {{ form.as_table }}
            </table>
            
            <input type="submit" value="Submit">
            {% csrf_token %}
        </form>
    </body>
    </html>
    View Code

    运行结果

    现在message输入框形式本应该是textarea形式,却是text line形式,可以通过修改forms类的参数来改变展现形式。

    forms.py文件

    from django import forms
    class ContactForm(forms.Form):
        subject = forms.CharField();
        email = forms.EmailField(required = False);
        message = forms.CharField(widget=forms.Textarea);

    field类表示有效逻辑,widget表示展现形式。max_length表示可以输入的最大字符数,min_length表示最少字符数。限定charfield。

    4、定制forms规则,当需要一个特别的有效性规则、并且需要经常使用,可以考虑定制一个规则。在forms类中实现方法

    比如不能使message输入的单词数少于4个,可以在类中写一个方法

    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100);
        email = forms.EmailField(required = False);
        message = forms.CharField(widget=forms.Textarea);
        
        def clean_message(self):
            message = self.cleaned_data['message']
            num_words = len(message.split())#获取单词数
            if num_words < 4:
                raise forms.ValidationError("Not enough words!")
            return message
    View Code

    注意:它是以clean_开头,以字段名称结束的方法,他将在校验时调用。

    我们需要在最后将校验的字段返回,否则None将会被返回,原始数据丢失。

    5、指定标签

    HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签是"Email"。可以使用

    label='Your e-mail address'例如:email = forms.EmailField(required=False, label='Your e-mail address' )

    6、定制form设计

    为了更加精确的控制显示效果,我们可以通过{{form.字段名}}进行单独的渲染


    三、表单的一些高级用法
    1 表单继承
    Form的子类还可以被继承,也可以多重继承,如果有些变量不想在子类中使用,可以使用Meta类中的fields或exclude来限制可用变量
    class Person(forms.Form):
        first =forms.CharField()
        last = forms.CharField()
        middle = forms.CharField()
    
    class AgedPerson(Person):
        age = forms.IntegerField()
        class Meta:
            exclude=('middle',)
    
    

    2 填写表单

    用request.POST来填充表单时,如果含有额外数据,form类会自动无视那些和他们定义的变量没关系的输入。



  • 相关阅读:
    Mac终端运行java程序
    Mac上csv导入mysql提示错误[Error Code] 1290
    Mac终端使用mysql
    将spark默认日志log4j替换为logback
    Cocos2d-x 3.x部署到安卓
    Cocos2d-x 3.0 场景切换
    visual studio 未将对象引用设置到对象的实例
    C++ list用法
    减而治之
    递归
  • 原文地址:https://www.cnblogs.com/zhaopengcheng/p/5439462.html
Copyright © 2020-2023  润新知