Django第七篇-----如何提交表单

目录

如何获取url的信息

其他可用来反爬的信息

一个简单的表单处理

简单的验证

第一个表单类

在视图中使用表单对象

改变字段的渲染方式

设定最大长度

设定初始值

自定义验证规则

指定标注


如何获取url的信息

HttpRequest 对象中有一些关于当前所请求 URL 的信息

其他可用来反爬的信息

request.META 的值是一个 Python 字典,包含请求的所有 HTTP 首部,例如用户的 IP 地址和用户代理(useragent,通常是 Web 浏览器的名称和版本)。注意,具体包含哪些首部取决于用户发送了什么首部,以及Web 服务器返回了什么首部。这个字典中常见的几个键有:

• HTTP_REFERER :入站前的 URL(可能没有)。(注意,要使用错误的拼写,即 REFERER 。)
• HTTP_USER_AGENT浏览器的用户代理(可能没有)。例如: "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" 。
• REMOTE_ADDR :客户端的 IP 地址,例如 "12.345.67.89" 。(如果请求经由代理,这个首部的值可能是一组 IP 地址,以逗号分隔,例如 "12.345.67.89,23.456.78.90" 。)

注意,因为 request.META 是个普通的 Python 字典,所以尝试访问不存在的键时,抛出 KeyError 异常。

# 不好
def ua_display_bad(request):
    ua = request.META['HTTP_USER_AGENT'] # 可能抛出 KeyError
    return HttpResponse("Your browser is %s" % ua)
# 好(版本 1)
def ua_display_good1(request):
    try:
        ua = request.META['HTTP_USER_AGENT']
    except KeyError:
        ua = 'unknown'
    return HttpResponse("Your browser is %s" % ua)
# 好(版本 2)
def ua_display_good2(request):
    ua = request.META.get('HTTP_USER_AGENT', 'unknown')
    return HttpResponse("Your browser is %s" % ua)

下面是一个简单的视图,显示 request.META 中的所有信息,以便查阅。

def display_meta(request):
    values = request.META.items()
    values.sort()
    html = []
    for k, v in values:
        html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v))
    return HttpResponse('<table>%s</table>' % '\n'.join(html))

view

{% extends "base.html" %}
{% block title %}My helpful display meta{% endblock %}
{% block h1 %}The display meta{% endblock %}
{% block item %}
<ul>
{% for item in item_list %}
<li>{{ item }}</li>{% endfor %}
</ul>
{% endblock %}

结果如下

一个简单的表单处理

如下配置

urls.py

url(r'^search-form/$', search_form),
url(r'^search/$', search),

views.py

def search_form(request):
    return render(request, 'search_form.html')

def search(request):
    if 'q' in request.GET:
        q = request.GET['q']
        books = Book.objects.filter(title__icontains=q)
        return render(request, 'search_results.html',
                      {'books': books, 'query': q})
    else:
        message = 'You submitted an empty form.'
    return HttpResponse(message)

search_form.html

<html>
<head>
<title>Search</title>
</head>
<body>
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>

 search_results.html

<html>
<head>
<title>Book Search</title>
</head>
<body>
<p>You searched for: <strong>{{ query }}</strong></p>
{% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
<ul>
{% for book in books %}
<li>{{ book.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>No books matched your search criteria.</p>
{% endif %}
</body>
</html>

简单的验证

def search(request):

    error = []
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            error.append('请填写内容')
        elif len(q) > 20 or len(q) == 0:
            error.append('字符串超过20')
        else:
            books = Book.objects.filter(title__icontains=q)
            return render(request, 'search_results.html',{'books': books, 'query': q})
    return render(request, 'search_form.html',{'error': error})
<html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
{% for error_ in error %}
<li>{{ error_ }}</li>
{% endfor %}
{% endif %}
<form action="/search/" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>

第一个表单类

Django 自带了一个表单库, django.forms ,它能处理本章所述的多数问题,从显示 HTML 表单到验证,都能胜任。下面我们使用这个 Django 表单框架为应用程序构建一个联系表单。

在 views.py 文件所在的目录( mysite )中创建 forms.py文件,然后输入下述内容:

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

打印查看

>>> from mysite.forms import ContactForm
>>> f = ContactForm()
>>> print(f.as_p())
>>> <p><label for="id_subject">Subject:</label> <input type="text" name="subject" required id=
"id_subject" /></p>
<p><label for="id_email">Email:</label> <input type="email" name="email" id="id_email" /><
/p>
<p><label for="id_message">Message:</label> <input type="text" name="message" required id=
"id_message" /></p>
>>> print(f['subject'])
<input id="id_subject" name="subject" type="text" />
>>> print f['message']
<input id="id_message" name="message" type="text" />

在视图中使用表单对象

views.py

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            ......
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm()
    return render(request, 'contact_form.html', {'form': form})

contact_form.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>
{% csrf_token %}
<input type="submit" value="Submit">
</form>
</body>
</html>

 urls.py

# ...
from mysite.views import hello, current_datetime, hours_ahead, contact
urlpatterns = [
    # ...
    url(r'^contact/$', contact),
]

这个表单使用 POST 处理(要修改数据),因此要关心跨站请求伪造(Cross Site Request Forgery,CSRF)。
幸好,我们无需太过担心,因为 Django 提供了非常易用的防护系统。简单来说,所有通过 POST 指向内部
URL 的表单都应该使用 {% csrf_token %} 模板标签。

改变字段的渲染方式

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

设定最大长度

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

超过10长度就会无法输入

设定初始值

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            send_mail(
                cd['subject'],
                cd['message'],
                cd.get('email', '[email protected]'), ['[email protected]'],)
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm(
            initial={'subject': 'max 10'}
        )
    return render(request, 'contact_form.html', {'form': form})

 自定义验证规则

from django import forms
class ContactForm(forms.Form):
    subject = forms.CharField(max_length=10)
    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

Django 的表单系统会自动查找名称以 clean_ 开头、以字段名结尾的方法。如果存在这样的方法,在验证过程中调用。这里, clean_message() 方法会在指定字段的默认验证逻辑(这个 CharField 是必填的)执行完毕后调用。

指定标注

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

猜你喜欢

转载自blog.csdn.net/Da___Vinci/article/details/84371941