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', 'noreply@example.com'), ['siteowner@example.com'],)
            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')

Django-oauth-toolkit是一个用于处理OAuth 2.0协议的第三方库,它简化了在Django应用中实现OAuth认证流程的过程。配置一个基本的授权页面主要包括以下几个步骤: 1. **安装**: 首先需要在你的Django项目中安装`django-oauth-toolkit`,可以使用pip命令: ``` pip install djangorestframework-django-oauth-toolkit ``` 2. **添加依赖到settings.py**: 将`rest_framework`和`oauth2_provider`添加到你的INSTALLED_APPS列表中。 3. **设置授权端点**: 在`urls.py`文件中,通常会包含OAuth2Provider的应用URL模式,比如: ```python from rest_framework import routers from oauth2_provider import views as o2p_views router = routers.DefaultRouter() router.register(r'authorize', o2p_views.AuthorizationView) router.register(r'token', o2p_views.TokenView) urlpatterns = [ ..., path('oauth/', include(router.urls)), ] ``` 4. **配置授权视图**: 需要创建一个模板文件,如`templates/oauth/authorize.html`,这个模板将展示给用户进行授权的表单。 5. **启动认证服务**: 在视图函数中,你可以选择启动一个本地服务器让用户访问授权页面,通常是通过`o2p_views.start_authorization_server()`。 6. **触发授权流程**: 用户在浏览器中打开授权页面后,需要同意应用程序的权限请求。完成授权后,会返回一个授权码或者直接生成一个access token。 7. **客户端配置**: 如果你有前端应用,需要注册客户端并获取客户端ID和密钥,以便在授权成功后进行后续的token请求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海人001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值