19.1.1 添加新主题

19.1.1  添加新主题 

让用户输入并提交信息的页面都是表单,那怕它看起来不像表单。

用户输入信息时,我们需要进行验证,确认提供的信息时正确的数据类型,且不是恶意的信息。

在Django中,创建表单的最简单方式是使用ModelForm,创建一个名为forms.py的文件,

将其存储到models.py所在的目录中

node2:/django/mysite/learning_log/learning_logs#cat forms.py
from django import forms
from .models import Topic
class TopicForm(forms.ModelForm):
   class Meta:
     model = Topic
     fields = ['text']
     labels = {'text':''}
	 
	 
我们首先导入了模块forms以及要使用的模型Topic.我们定义了一个名为TopicForm的类,它继承了forms.ModelForm

最简单的ModelForm版本只包含一个内嵌的Meta类,它告诉Django根据哪个模型创建表单,以及在表单中包含哪些字段


在2处,我们根据模型Topic创建一个表单,该表单只包含字段text

2.URL 模式new_topic:

这个新网页的URL应简短而具有描述性,因此当用户要添加新主题时,

我们将切换到http://localhost:8000/new_topic/  下面是网页new_topic的URL模式,我们将其添加到learn_logs/urls.py

node2:/django/mysite/learning_log/learning_logs#cat urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
   
   url(r'^$',views.index,name='index'),
   url(r'^topics/$',views.topics,name='topics'),
   url(r'^new_topic/$',views.new_topic,name='new_topic'),
   url(r'^topics/(?P<topic_id>d+)/$',views.topic,name='topic'),
   
   
这个URL模式将请求交给视图函数new_topic(),接下来我们将编写这个函数

3.视图函数new_topic()

函数new_topic()需要处理两种情形,刚进入new_topic网页(在这种情况下,它应显示一个空表单):

对提交的表单数据进行处理,并将用户重定向到网页topics 


node2:/django/mysite/learning_log/learning_logs#cat views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render 
from django.http import HttpResponseRedirect 
from django.core.urlresolvers import reverse

from django.shortcuts import render
from .models import Topic
from .forms import TopicForm

# Create your views here.
def index(request):
  return render(request,'learning_logs/index.html')
def topics(request):
   print 'call topics'
   topics = Topic.objects.order_by('date_added')
   context = {'topics':topics}
   return render(request,'learning_logs/topics.html',context)
def new_topic(request):
     if request.method != 'POST':
         form = TopicForm()
     else:
     #POST提交的数据,对数据进行处理
         form = TopicForm(request.POST)
         if form.is_valid():
            form.save()
            print '11111111111111'
            return HttpResponseRedirect(reverse('learning_logs:topics'))
     print '2222222222222'
     context = {'form' : form}
     return render(request,'learning_logs/new_topic.html',context)
def topic(request,topic_id):
   print topic_id
   topic = Topic.objects.get(id=topic_id)
   entries = topic.entry_set.order_by('-date_added')
   context = {'topic':topic,'entries':entries}
   print context
   return render(request,'learning_logs/topic.html',context) 


我们导入了HttpResponseRedirect类,用户提交主题后我们将使用这个类将用户重定向到topics网页

return HttpResponseRedirect(reverse('learning_logs:topics'))

4.GET请求和POST请求

创建Web应用程序时,将用到的两种主要请求类型是GET请求和POST请求。


函数new_topic()将请求对象作为参数,用户初次请求该网页时,其浏览器将发送GEY请求:

用户填写并提交表单时,其浏览器将发送POST请求。根据请求的类型 

我们可以确定用户请求的是空表单(GET请求)还是要求对填写好的表单进行处理

1处的测试确定请求方法是GET还是POST,如果请求方法不是POST,请求就可能是GET

因此我们需要返回一个空表单

如果请求方法为POST,将执行else代码块,对提交的表单数据进行处理。

我们使用用户输入的数据(它们存储在request.POST中)创建一个TopicForm实例  



要将提交的信息保存到数据库,必须先检查确定它们是有效的 

函数is_valid()核实用户填写了所有必不可少的字段(表单字段默认都必不可少的)

且输入的数据与要求的字段类型一致  


5.模板new_topic:

下面来创建新模板new_topic.html,用于显示我们刚创建的表单:

node2:/django/mysite/learning_log/learning_logs#cat templates/learning_logs/new_topic.html 
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Add a new topic:</p>
<form action="{% url 'learning_logs:new_topic' %}" method='post'>
{% csrf_token %}
{{ form.as_p}}
<button name="submit">add topic</button>
</form>
{% endblock content %}

这个模板继承了base.html,因此其基本结构与项目"学习笔记”的其他页面相同

在1处,我们定义了一个HTML表单。实参action告诉服务器将提交的表单数据发送到哪里,

这里我们将它发回给视图函数new_topic() 

实参method让浏览器以POST请求的方式提交数据

Django使用模板标签{% csrf_token %} 来防止攻击者利用表单来获得对服务器未经授权的访问 


6 连接到页面new_topic

接下来,我们在页面topics中添加一个到页面new_topic的连接

node2:/django/mysite/learning_log/learning_logs#cat templates/learning_logs/topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
</ul>
<a href="{% url 'learning_logs:new_topic' %}">Add a new topic:</a>
{% endblock content %}



原文地址:https://www.cnblogs.com/hzcya1995/p/13348712.html