django

django就是有MTV
原来的控制的C由框架自己搞定了,
M就是Model,写的是业务对象和数据库的关系,从数据库读取数据,给视图View获取和返回数据
T是模板,给用户展示内容

V和T是展示哪些数据和模板怎么展现两部分

以要增加书籍为例
首先在T上,要有一个html写这个


image.png

这个里面有一个url 'lib:addBook2'对应的是addBook2,要在url.py里和View连起来 ,url.py里有path('addBook5/',views.addBook,name='addBook2'),

MVC

在说 MTV 模式之前,让我们来简单的说说著名的 MVC 模式。

MVC,是模型(Model)-视图(View)-控制器(Controller)的缩写。其具体定义如下:

  • M:模型(Model),数据存取层,负责业务对象和数据库对象。
  • V:视图(View),与用户的交互,负责显示与怎样显示。
  • C:控制器(Controller),接受用户动作,调用模型,输出相应视图。

三者以一种插件似的,松耦合的方式连接在一起。

7-2.1-1

MTV

Django 的 MTV 设计模式是借鉴和遵循 MVC 的。

MTV 具体定义如下:

  • M:模型(Model),负责业务对象和数据库的关系映射。
  • T:模板(Template),负责如何把页面展示给用户。
  • V:视图(View),负责业务逻辑,并在适当时候调用模型和模板。

URL 分发器

URL 分发器的作用是将页面请求分发给不同的视图(View)处理,视图再调用相应的模型(Model)和模板(Template)。

Django Web 框架:

7-2.1-2

一个误区是把 MVC 模式与 MTV 模式等价替换。其实这样是不对的。

在 MTV 模式中,MVC 中的 View 分成了视图 View(展现哪些数据)和模板 Template(如何展现)2 个部分,而控制器(Controller)这个要素由框架自己来实现了,我们需要做的就是把 URL 对应到视图 V 就可以了,通过这样的 URL 配置,系统将一个请求发送到一个合适的视图。

设计表单

在上一个实验中的 myApp/templates/myApp/detail.html 里,添加一个表单。

<form action="" method="post" name="addBook">
  {% csrf_token %}
  <p><span>书名:</span><input type="text" name="name" /></p>
  <p><span>作者:</span><input type="text" name="author" /></p>
  <p><span>出版社:</span><input type="text" name="pub_house" /></p>
  <input type="submit" value="添加" />
</form>

简要说明:

  • 上面的模板是输入相应的书名、作者和出版社后,点击添加,将数据存储到数据库并刷新页面显示出来。
  • 我们设置表单的 action="/addBook/",并设置 method="post"。使用 method="post"(与其相对的是 method="get")是非常重要的,因为这个提交表单的行为会改变服务器端的数据,无论何时,当你需要创建一个改变服务器端数据的表单时,请使用 method="post"。这不是 Django 的特定技巧,这是优秀的网站开发技巧。
  • 由于我们创建一个 POST 表单(它具有修改数据的作用),所以我们需要小心跨站点请求伪造。 但你不必太过担心,因为 Django 已经拥有一个用来防御它的非常容易使用的系统。 简而言之,所有针对内部 URL 的 POST 表单都应该使用 {% csrf_token %} 模板标签。

命名空间:

教程项目只有一个应用 myApp。在一个真实的 Django 项目中,可能会有五个,十个,二十个,甚至更多应用。Django 如何分辨重名的 URL 呢?

举个例子,myApp 应用有 detail 视图,可能另一个博客应用也有同名的视图。Django 如何知道 action="" 标签到底对应哪一个应用的 URL 呢?

答案是:在根 URLconf 中添加命名空间。在 myProject/urls.py 文件中稍作修改,加上 app_name 设置命名空间:

from django.contrib import admin
from django.urls import path
from myApp import views

app_name = 'myApp' # 添加这一行
urlpatterns = [
    # path('admin/', admin.site.urls),
    path('', views.detail, name='detail'),
    path('addBook/', views.addBook, name='addBook'),
]

现在回到 myApp/templates/myApp/detail.html 更改 action

<form action="/addBook/" method="post" name="addBook"></form>

添加书籍

创建 addBook 函数来实现我们添加书籍的功能。

将下面的代码添加到 myApp/views.py:

# myApp/views.py
from django.http import HttpResponseRedirect
from django.urls import reverse

def addBook(request):
    if request.method == 'POST':
        temp_name = request.POST['name']
        temp_author = request.POST['author']
        temp_pub_house = request.POST['pub_house']

    from django.utils import timezone
    temp_book = Book(name=temp_name, author=temp_author, pub_house=temp_pub_house, pub_date=timezone.now())
    temp_book.save()

    # 重定向
    return HttpResponseRedirect(reverse('detail'))

在 myProject/urls.py 里添加 URL 地址映射:

# myProject/urls.py
path('addBook/', views.addBook, name='addBook'),

简单说明:

  • request.POST 是一个类字典对象,可以通过关键字的名字获取提交的数据。 这个例子中,request.POST['name'] 以字符串形式返回name的值。request.POST 的值永远是字符串。
  • 在添加书籍之后,代码返回一个 HttpResponseRedirect 而不是常用的 HttpResponseHttpResponseRedirect 只接收一个参数:用户将要被重定向的 URL。
  • 你应该在每次处理 POST 数据时,都返回HttpResponseRedirect。这也不是 Django 的特定技巧,这是优秀的网站开发的实践。
  • 在这个例子中,我们在 HttpResponseRedirect 的构造函数中使用 reverse() 函数。这个函数避免了我们在视图函数中硬编码 URL。它需要我们给出想要跳转的视图的名字和该视图所对应的 URL 模式中需要给该视图提供的参数。reverse() 调用后将返回这样一个字符串:/detail/

添加书籍功能完成,现在可以随意添加书籍。

打开 Web 服务访问链接就可以查看效果:

添加前:

6-2.2-1

添加后:

6-2.2-2

删除书籍
删除书籍功能实现起来也很简单。

首先,在 myApp/detail.html 中设计我们的模板。

{% for book in book_list.all %}
    <tr>
        <td>{{ book.name }}</td>
        <td>{{ book.author }}</td>
        <td>{{ book.pub_house }}</td>
        <td>{{ book.pub_date }}</td>
        <td><a href="{% url 'delBook' book.id %}">删除</a></td><!--只添加这一行-->
    </tr>
{% endfor %}
</table>

可以看出,只需要在每个书籍后面添加一个删除的按钮。删除时也传递了需要删除的图书的 id

接着,配置 url,只需在 myProject/urls.py 中添加这一行:

# myProject/urls.py
path('delBook/<int:book_id>', views.deleteBook, name='delBook'),

这里 <int:book_id> 是接收传递的参数 book_id

最后设计视图函数:

# myApp/views.py
def deleteBook(request, book_id):
    bookID = book_id
    Book.objects.filter(id=bookID).delete()

    # 重定向
    return HttpResponseRedirect(reverse('detail'))

这个视图中,获取到 book 的 id,根据 id 来删除指定书籍。最后跟上面的添加书籍函数相同,使用重定位刷新页面。

打开 Web 服务访问链接查看效果:

删除后:

6-2.3-1

学习资料来自实验楼

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容