上一篇文章里,我们做了一个alionlineecs(阿里云线上环境服务器)的添加界面,但是要知道我们的计划里是有六个分支的,而alionlineecs仅仅是其中之一,要是每一个都这么写的话,那么views.py肯定又臭又长,充满了大量的复制片段。
对于这样的情况,我们就用一种统一的方式,把这些alionlineecs\alifuncecs\slb\rds等等这些分支当成一个变量,再自定义两个url,比如lists这个url就是展示功能,当在浏览器里输入"外网地址:8000/lists/alionlinecs"的时候,就会出现阿里线上环境服务器的展示界面;当在浏览器里输入"外网地址:8000/lists/slb"的时候,就会出现阿里负载均衡的展示界面。同时也额外设定一个add的url,当在浏览器里输入"外网地址:8000/add/alionlinecs"的时候,就会出现阿里线上环境服务器的添加界面。这样就同意好管理多了。
于是我们先编辑vim forms.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<code># -*- coding: UTF-8 -*- </code>
<code>from</code> <code>django.forms </code><code>import</code> <code>ModelForm</code>
<code>from</code> <code>.models </code><code>import</code> <code>alionlineECS,alifuncECS,ksonlineECS,ksfuncECS,SLB,RDS</code>
<code>#定义ECS的Form,Form名字为 模式名+Form</code>
<code>class</code> <code>alionlineForm(ModelForm):</code>
<code> </code><code>#自定义ModelForm的内容</code>
<code> </code><code>class</code> <code>Meta:</code>
<code> </code><code>#该ModelForm参照Model: ECS</code>
<code> </code><code>model </code><code>=</code> <code>alionlineECS</code>
<code> </code><code>#在Form中不显示node_signer这个字段 </code>
<code> </code><code>exclude </code><code>=</code> <code>[</code><code>'ecs_signer'</code><code>]</code>
<code> </code>
<code>class</code> <code>alifuncForm(ModelForm):</code>
<code> </code><code>model </code><code>=</code> <code>alifuncECS</code>
<code>class</code> <code>ksonlineForm(ModelForm):</code>
<code> </code><code>model </code><code>=</code> <code>ksonlineECS</code>
<code>class</code> <code>ksfuncForm(ModelForm):</code>
<code> </code><code>model </code><code>=</code> <code>ksfuncECS</code>
<code>class</code> <code>SLBForm(ModelForm):</code>
<code> </code><code>model </code><code>=</code> <code>SLB</code>
<code> </code><code>exclude </code><code>=</code> <code>[</code><code>'slb_signer'</code><code>]</code>
<code>class</code> <code>RDSForm(ModelForm):</code>
<code> </code><code>model </code><code>=</code> <code>RDS</code>
<code> </code><code>exclude </code><code>=</code> <code>[</code><code>'rds_signer'</code><code>]</code>
然后把urls.py进行一下整顿:
<code>from</code> <code>django.conf.urls </code><code>import</code> <code>url</code>
<code>from</code> <code>django.contrib </code><code>import</code> <code>admin</code>
<code>import</code> <code>Online.views</code>
<code>urlpatterns </code><code>=</code> <code>[</code>
<code> </code><code>url(r</code><code>'^admin/'</code><code>,admin.site.urls),</code>
<code> </code><code>url(r</code><code>'^lists/(?P<table>\w+)/$'</code><code>,Online.views.lists,name</code><code>=</code><code>'lists'</code><code>),</code>
<code> </code><code>url(r</code><code>'^add/(?P<table>\w+)/$'</code><code>,Online.views.add,name</code><code>=</code><code>'add'</code><code>),</code>
<code>]</code>
最麻烦的地方就是views.py,这个变动比较大了:
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<code># -*- coding: UTF-8 -*-</code>
<code>from</code> <code>django.shortcuts </code><code>import</code> <code>render,redirect</code>
<code>from</code> <code>forms </code><code>import</code> <code>alionlineForm,alifuncForm,ksonlineForm,ksfuncForm,SLBForm,RDSForm</code>
<code>def</code> <code>lists(request,table):</code>
<code> </code><code>#不同的需求跳到不同的界面</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'alionlineECS'</code><code>:</code>
<code> </code><code>data </code><code>=</code> <code>alionlineECS.objects.</code><code>all</code><code>()</code>
<code> </code><code>list_template </code><code>=</code> <code>'alionlineECS_list.html'</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'alifuncECS'</code><code>:</code>
<code> </code><code>data </code><code>=</code> <code>alifuncECS.objects.</code><code>all</code><code>()</code>
<code> </code><code>list_template </code><code>=</code> <code>'alifuncECS_list.html'</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'ksonlineECS'</code><code>:</code>
<code> </code><code>data </code><code>=</code> <code>ksonlineECS.objects.</code><code>all</code><code>()</code>
<code> </code><code>list_template </code><code>=</code> <code>'ksonlineECS_list.html'</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'ksfuncECS'</code><code>:</code>
<code> </code><code>data </code><code>=</code> <code>ksfuncECS.objects.</code><code>all</code><code>()</code>
<code> </code><code>list_template </code><code>=</code> <code>'ksfuncECS_list.html'</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'SLB'</code><code>:</code>
<code> </code><code>data </code><code>=</code> <code>SLB.objects.</code><code>all</code><code>()</code>
<code> </code><code>list_template </code><code>=</code> <code>'slb_list.html'</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'RDS'</code><code>:</code>
<code> </code><code>data </code><code>=</code> <code>RDS.objects.</code><code>all</code><code>()</code>
<code> </code><code>list_template </code><code>=</code> <code>'rds_list.html'</code>
<code> </code><code>#建立一个context,将值传递到对应的页面</code>
<code> </code><code>context </code><code>=</code> <code>{</code>
<code> </code><code>'data'</code><code>:data,</code>
<code> </code><code>}</code>
<code> </code><code>#跳转到相应页面,并将具体的值传递过去</code>
<code> </code><code>return</code> <code>render(request,list_template,context)</code>
<code>def</code> <code>add(request,table):</code>
<code> </code><code>#根据提交的请求不同,获取来自不同Form的表单数据</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'alionlineECS'</code><code>:</code>
<code> </code><code>form </code><code>=</code> <code>alionlineForm(request.POST </code><code>or</code> <code>None</code><code>)</code>
<code> </code><code>form </code><code>=</code> <code>alifuncForm(request.POST </code><code>or</code> <code>None</code><code>)</code>
<code> </code><code>form </code><code>=</code> <code>ksonlineForm(request.POST </code><code>or</code> <code>None</code><code>)</code>
<code> </code><code>form </code><code>=</code> <code>ksfuncForm(request.POST </code><code>or</code> <code>None</code><code>)</code>
<code> </code><code>form </code><code>=</code> <code>SLBForm(request.POST </code><code>or</code> <code>None</code><code>)</code>
<code> </code><code>form </code><code>=</code> <code>RDSForm(request.POST </code><code>or</code> <code>None</code><code>)</code>
<code> </code><code>#判断form是否有效</code>
<code> </code><code>if</code> <code>form.is_valid():</code>
<code> </code><code>#创建实例,需要做些数据处理,暂不做保存</code>
<code> </code><code>instance </code><code>=</code> <code>form.save(commit</code><code>=</code><code>False</code><code>)</code>
<code> </code><code>#将登录用户作为登记人</code>
<code> </code><code>instance.ecs_signer </code><code>=</code> <code>request.user</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'alifuncECS'</code><code>:</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'ksonlineECS'</code><code>:</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'ksfuncECS'</code><code>:</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'SLB'</code><code>:</code>
<code> </code><code>instance.slb_signer </code><code>=</code> <code>request.user</code>
<code> </code><code>if</code> <code>table </code><code>=</code><code>=</code> <code>'RDS'</code><code>:</code>
<code> </code><code>instance.rds_signer </code><code>=</code> <code>request.user</code>
<code> </code><code>#保存该实例</code>
<code> </code><code>instance.save()</code>
<code> </code><code>#跳转至列表页面 </code>
<code> </code><code>return</code> <code>redirect(</code><code>'lists'</code><code>,table</code><code>=</code><code>table)</code>
<code> </code><code>#创建context来集中处理需要传递到页面的数据 </code>
<code> </code><code>'form'</code><code>: form,</code>
<code> </code><code>#如果没有有效提交,则仍留在原来页面 </code>
<code> </code><code>return</code> <code>render(request, </code><code>'add.html'</code><code>,context)</code>
上面我们写了很多个html,那么现在就要一个一个的补全这些html,比如alionlineECS_list.html,这里放上我们需要对外展示的节点,注意要跟model.py的各项一一对应:
<code> </code><code><</code><code>meta</code> <code>charset</code><code>=</code><code>"UTF-8"</code><code>> </code>
<code> </code><code><</code><code>title</code><code>></</code><code>title</code><code>> </code>
<code></</code><code>head</code><code>></code>
<code><</code><code>body</code><code>></code>
<code> </code><code><</code><code>table</code><code>></code>
<code> </code><code><</code><code>tr</code><code>></code>
<code> </code><code><</code><code>th</code><code>>云服务器名称</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>云服务器类型</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>云服务器内网地址</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>云服务器外网地址</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>云服务器外网带宽</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>云服务器配置</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>备注</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>登记人</</code><code>th</code><code>></code>
<code> </code><code></</code><code>tr</code><code>></code>
<code> </code><code>{% for item in data %}</code>
<code> </code><code><</code><code>tr</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_name }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_type }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_inip }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_outip }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_ipwidth }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_spec }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_remarks }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.ecs_signer }}</</code><code>td</code><code>></code>
<code> </code><code></</code><code>tr</code><code>></code>
<code> </code><code>{% endfor %}</code>
<code> </code><code></</code><code>table</code><code>></code>
<code></</code><code>body</code><code>></code>
<code></</code><code>html</code><code>></code>
而SLB.html就长这个样子:
<code><!DOCTYPE html></code>
<code><</code><code>html</code><code>></code>
<code><</code><code>head</code> <code>lang</code><code>=</code><code>"en"</code><code>> </code>
<code> </code><code><</code><code>th</code><code>>负载均衡名称</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>网络类型</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>转发规则</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>ip地址</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>负载均衡协议</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>前端端口</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>后端端口</</code><code>th</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_name }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_type }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_algorithm }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_ip }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_protocol }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_fport }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_bport }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_protocol2 }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_fport2 }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_bport2 }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_signer }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.slb_remarks }}</</code><code>td</code><code>></code>
RDS.html写成这个样子:
<code> </code><code><</code><code>th</code><code>>数据库名称</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>数据库类型</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>mysql版本</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>数据库规格</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>数据库地址</</code><code>th</code><code>></code>
<code> </code><code><</code><code>th</code><code>>存储空间</</code><code>th</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_name }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_type }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_mysql }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_spec }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_remark }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_ip }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_status }}</</code><code>td</code><code>></code>
<code> </code><code><</code><code>td</code><code>>{{ item.rds_signer }}</</code><code>td</code><code>></code>
这个时候我们启动django来到浏览器里,在地址栏输入:外网地址:8000/lists/alionlinecs,就会看到之前的那个添加“阿里云线上服务器”的界面,如图:
在点击了提交之后,就会看到地址栏里的add变成了lists,达到了我们的预期目标:
1. Django处理请求的方式
1) Django通过URLconf模块来进行判断。通常情况下,这就是ROOT_URLCONF配置的价值,但是如果请求携带了一个urlconf的属性(通常被中间件设置),那么这个被携带的urlconf将会替代ROOT_URLCONF的配置。
3) Django会遍历每个URL pattern,自上而下,并且选取收割匹配请求URL的pattern。
4) 一旦匹配某个url pattern的正则表达式,Django将导入并调用相关的view(这是一个简单的python函数,或者是一个class-based view)
这个view将会传递下列参数:
l 一个HttpRequest的实例
l 如果匹配了URL中一个no named group,那么参数将会按根据URL中的位置一一对应
l 如果匹配了URL中一个named group,且参数传递是通过named group来匹配的,那么参数将会被指定的kwargs代替。
5) 如果没有任何一个正则表达式被匹配,那么Django会抛出异常,并报错。
2. URL中的named group
URL可以通过named group方式传递指定参数,语法为: (?P<name>pattern), name 可以理解为所要传递的参数的名称,pattern代表所要匹配的模式。例如,
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
那么year,month将会对应views传递过来的year,month的值,而后面紧跟的则代表正则表达匹配的模式。
3. URL的反向解析
通常来说在处理完一个表单之后,网页会发生跳转。通常写URL我们都避免硬编码,这样不方便后期的调整。通常我们需要从URL获取两种内容,最主要是view能够通过URL获取一些标识并处理,另一些信息则是传递过来的参数。
Django提供了一种解决方案,URL mapper是与URL设计一一对应。你可以通过URLconf来实现,并反向使用它。例如:
由用户通过浏览器发起URL请求,调用view,并将URL中的参数传递给view
通过view并附上相应参数,找到相应匹配的URL。
后者我们称之为对URLs的反向解析。反向解析的例子,
url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
Django在不同的层次也提供了一些工具来实现URL的反向解析。
在template中:使用url标签
在python中:使用django.core.urlresolvers.reverse()函数
在更高层次处理model实例时,可以使用get_absolute_url()方法
本文转自 苏幕遮618 51CTO博客,原文链接:http://blog.51cto.com/chenx1242/1948971