The Django Book 第七章 表单(1)

本书网站链接

从Request对象中获取数据:
每个view函数的第一个参数是一个HttpRequest对象,如下所示:

from django.http import HttpResponse
def hello(request):
    return HttpResponse("Hello world")

request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息。这个字典中几个常见的键值有:

提交的数据信息:
除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和request.POST。二者都是类字典对象,你可以通过它们来访问GET和POST数据。

POST数据是来自HTML中的〈form〉标签提交的,而GET数据可能来自〈form〉提交也可能是URL中的查询字符串(the query string)。


一个简单的表单处理示例:
views.py

from django.shortcuts import render_to_response
def search_form(request):
    return render_to_response('search_form.html')

search_form.html



    Search


    

urls.py

from mysite.books import views
urlpatterns = patterns('',
    # ...
    (r'^search‐form/$', views.search_form),
    # ...
)

然后,启动服务,我们可以打开一个搜索框。然而,点提交会报错,下面继续实现功能。

# urls.py
urlpatterns = patterns('',
    # ...
    (r'^search‐form/$', views.search_form),
    (r'^search/$', views.search),
    # ...
)


# views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from mysite.books.models import Book

def search(request):
    if 'q' in request.GET and request.GET['q']:
        q = request.GET['q']
        books = Book.objects.filter(title__icontains=q)
        return render_to_response('search_results.html',{'books': books, 'query': q})
    else:
        return HttpResponse('Please submit a search term.')

search_results.html

You searched for: {{ query }}

{% if books %}

Found {{ books|length }} book{{ books|pluralize }}.

    {% for book in books %}
  • {{ book.title }}
  • {% endfor %}
{% else %}

No books matched your search criteria.

{% endif %}

改进表单:
views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response
from mysite.books.models import Book

def search_form(request):
    return render_to_response('search_form.html')
    
def search(request):
    if 'q' in request.GET and request.GET['q']:
        q = request.GET['q']
        books = Book.objects.filter(title__icontains=q)
        return render_to_response('search_results.html',{'books': books, 'query': q})
    else:
        **return render_to_response('search_form.html', {'error': True})**

search_form.html



    Search


    **{% if error %}**
    **

Please submit a search term.

** **{% endif %}**

最终改进:

def search(request):
    error = False
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            error = True
        else:
            books = Book.objects.filter(title__icontains=q)
            return render_to_response('search_results.html',{'books': books, 'query': q})
    return render_to_response('search_form.html',{'error': error})

html里修改:

简单的验证:
服务器端的验证
views.py

def search(request):
    **errors = []**
    if 'q' in request.GET:
        q = request.GET['q']
        if not q:
            **errors.append('Enter a search term.')**
        elif len(q) > 20:
            **errors.append('Please enter at most 20 characters.')**
        else:
            books = Book.objects.filter(title__icontains=q)
            return render_to_response('search_results.html',{'books': books, 'query': q})
    return render_to_response('search_form.html',{**'errors': errors** })

search_form.html



    Search


    **{% if errors %}**
        **
    ** **{% for error in errors %}** **
  • {{ error }}
  • ** **{% endfor %}** **
** **{% endif %}**

另一个表单,编写Contact表单:
contact_form.html



    Contact us


    

Contact us

{% if errors %}
    {% for error in errors %}
  • {{ error }}
  • {% endfor %}
{% endif %}

Subject:

Your e‐mail (optional):

Message:

views.py

from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

def contact(request):
    errors = []
    if request.method == 'POST':
        if not request.POST.get('subject', ''):
            errors.append('Enter a subject.')
        if not request.POST.get('message', ''):
            errors.append('Enter a message.')
        if request.POST.get('email') and '@' not in request.POST['email']:
            errors.append('Enter a valid e‐mail address.')
    if not errors:
        send_mail(
            request.POST['subject'],
            request.POST['message'],
            request.POST.get('email', '[email protected]'),
            ['[email protected]'],
        )
        return HttpResponseRedirect('/contact/thanks/')
    return render_to_response('contact_form.html',{'errors': errors})

上面会出现一个问题,原因就是: 若用户刷新一个包含POST表单的页面,那么请求将会重新发送造成重复。这通常会造成非期望的结果,比如说重复的数据库记录;在我们的例子中,将导致发送两封同样的邮件。如果用户在POST表单之后被重定向至另外的页面,就不会造成重复的请求了。

改进结果:
views.py

from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

def contact(request):
    errors = []
    if request.method == 'POST':
        if not request.POST.get('subject', ''):
            errors.append('Enter a subject.')
        if not request.POST.get('message', ''):
            errors.append('Enter a message.')
        if request.POST.get('email') and '@' not in request.POST['email']:
            errors.append('Enter a valid e‐mail address.')
    if not errors:
        send_mail(
            request.POST['subject'],
            request.POST['message'],
            request.POST.get('email', '[email protected]'),
            ['[email protected]'],
        )
        return HttpResponseRedirect('/contact/thanks/')
    return render_to_response('contact_form.html',{'errors': errors
    **'subject': request.POST.get('subject', ''),**
    **'message': request.POST.get('message', ''),**
    **'email': request.POST.get('email', ''),**})

contact_form.html



    Contact us


    

Contact us

{% if errors %}
    {% for error in errors %}
  • {{ error }}
  • {% endfor %}
{% endif %}

Subject:

Your e‐mail (optional):

Message:

你可能感兴趣的:(The Django Book 第七章 表单(1))