刘老师说这块很重要.....
应该是很重要, 大概看了一下, 这里面关于 views 中函数作用, 大概看来可能就是相应请求, 传入数据和跳转, 基本功能上貌似这些框架都差不多吧(其实我并没用过 3 个框架以上....)
从功能上想, 网站必然包含了许多实现具体功能和数据展示的页面, 而现在在做的就是构成这些.
那么一个网页他的样子 (模板) 就是 html, 那么他的灵魂在这里就是 views. 这样想似乎就比较清楚.
在构思的时候都是默认躯体存在, 设计者需要先设置他的灵魂
在 polls/views.py 中添加如下函数:
- def detail(request, question_id):
- return HttpResponse("You're looking at question %s." % question_id)
- def results(request, question_id):
- response = "You're looking at the results of question %s."
- return HttpResponse(response % question_id)
- def vote(request, question_id):
- return HttpResponse("You're voting on question %s." % question_id)
这里可以大概得出结论, 我们在 views.py 中做的所有函数几乎都是返回了一个 HttpResponse 对象
这个对象呢有这样几个属性:
content: 表示返回的内容, 字符串类型
charset: 表示 response 采用的编码字符集, 字符串类型
status_code: 响应的 HTTP 响应状态码 404 什么的
content-type: 指定输出的 MIME 类型
写好这几个函数, 也就需要配置一下二级路由, 服务器找到 App polls 的路径我理解为了这里的一级路由, 是在 pysite(我的 web 项目名)的 urls 里面配置的, 那么当在 App 之下在有页面时候同样就需要在 polls 的 urls 中进行路径配置, 好让服务器找到对应的地址.
- from django.urls import path
- from . import views
- urlpatterns = [
- # ex: /polls/
- path('', views.index, name='index'),
- # ex: /polls/5/
- path('<int:question_id>/', views.detail, name='detail'),
- # ex: /polls/5/results/
- path('<int:question_id>/results/', views.results, name='results'),
- # ex: /polls/5/vote/
- path('<int:question_id>/vote/', views.vote, name='vote'),
- ]
- <int:question_id> 这个东西, 这样想, 某个 int 类型的值, 传进来并将其赋给 question_id 变量, 还记得前面我们在 views 中写的函数吗, 其中参数除了 request 之外还有一个 question_id, 简直伏笔, 刘老师真骚人也....
牛人写书往往也这样, 开始看的你头疼, 知道看到某处, 武功及大成, 融会贯通, 一通百通.
这时候你在 localhost:8000/polls / 某个数字 访问的时候就会对应的出现不同效果, 看 detail 函数就能理解到.
这些能看得到就证明灵魂已经能运转了, 虽然他还没有躯体, 可能就像一个嗷嗷待哺的贾维斯一样吧, 史塔克牛逼
path()达成的效果是这样的, 这里已经是在找二级路由也就是, 从你地址栏输入的 polls / 后面开始找满足参数里面那个正则形式的, 就调用视图下某个函数
比如在
path('', views.index, name='index'), 即为如果 polls / 后面莫得东西, 那就走 index 函数去进行跳转传参,
path('<int:question_id>/', views.detail, name='detail'), 如果 polls / 后面只跟了一个数字 那就调用那个 views 中叫 detail 的函数
and so on .............................
然后刘老师搞了个能调用数据库中信息展示的函数, 也就是把 detail 进行了改变, 让页面能正儿八经做些事, 而不是傻冒的打印一句绝大多数字不会改变的字符串
更改一下 vies.py
- from django.http import HttpResponse
- from .models import Question
- def index(request):
- latest_question_list = Question.objects.order_by('-pub_date')[:5]
- output = ','.join([q.question_text for q in latest_question_list])
- return HttpResponse(output)
学过 MySQL 你看见 order by 就知道他要排序, 根据时间的相反数, 鬼知道为什么要用 1970 年到其日期之间的毫秒数, 知道也不想理解, 内心无法接收. 所以他这里根据时间的相反数, 可以想象, 这个毫秒数越大时间越 "新", 这里不用多想, 框架后面对应的必然有一条 ORDER BY 语句, 那个是要传一个列进去, 这句话默认是升序的, 如果这样的话, 最新的时间就会排在最下面了. 而我们想要的影噶是把最新的放在上面, 后来者居上, 这就解释得通了.(强行解释)
好的 detail 有了他的灵魂, 你还需要给他一个躯体, 这怎么感觉像是在看复仇者联盟 2 一样, 旺达的老公要出来了, 搞了这么久原来是托尼给贾维斯找了个女朋友, 还送了个定情原石. 哦! woc, 女朋友,,,,, 女......., 是啊百合是多么纯洁而浪漫
咳咳, 继续
django 中提到一个渲染, 说白了就是用一个 HttpResponse 对象把东西传过去. 然后页面再执行一些东西, 页面, 想想能干啥? 不就是显示屏和输入设备的功能吗, 给你看和让你点让你敲.
在这里, 当我们创建项目的时候就有一个雪青色的文件夹放在那里, 叫做 templates.....(邪恶), 这里只是拿出来说这个名字, 你要放的模板不在这里, 你需要在你对应的 App 的目录下面新建一个文件夹叫做 templates, 而且在这之下新建一个和 App 同名的文件夹比如这里的路径是 polls/templates/polls/
这里是你接下来要存放模板的地方, 这样做是为了解决一些共有问题, 很多时候集体主义状态很乱, 虽然现实中多数由于管理者能力不足导致, 但是本身确实有局限性, 比如这里说你们都是女生, 那么单说女生, 谁知道找哪一位呢? 集体主义有时候强制把一些东西变成了公共状态, 而如果设定不是很合理就必然会乱, 想想感觉得到, 当然事物是相对的, 集体的弊端需要个人弥补, 个人也有难以单独实现的事情. 阴阳调和即可.
所以请按照这个规范来创建, 圈里都这样 干, 你干是不干? 刘老师教程说叫做独立命名空间, 帅气
由于接下来要在 index 页面搞事情,
先吧 index 的灵魂写好:
数据库是要自己搞的哦, 具体参考前面的篇章
在 views.py 中修改:
- def index(request):
- latest_question_list = Question.objects.order_by('-pub_date')[:5]
- template = loader.get_template('polls/index.html')
- context = {
- 'latest_question_list': latest_question_list,
- }
- return HttpResponse(template.render(context, request))
创建好目录之后进去新建一个 HTML 文件
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- </head>
- <body>
- {% if latest_question_list %}
- <ul>
- {% for question in latest_question_list %} {# 被注释
- <li>
- <a href="/polls/{{ question.id }}/">
- {{ question.question_text }}
- </a>
- </li>
- #}
- <li>
- <a href="{% url'detail'question.id %}">
- {{ question.question_text }}
- </a>
- </li>
- {% endfor %}
- </ul>
- {% else %}
- <p>
- No polls are available.
- </p>
- {% endif %}
- </body>
- </HTML>
这就是现在的效果, 里面加了一个超链接, 超链接的内容是从数据库中查询到的 question_text 的内容, 如果想去做些很好看的页面, 建议去 mooc 看 HTML,CSS 等学一翻就好, 人活着没意思, 让你前进的是好奇心.
然后刘老师告诉你, 刚才的写法过时了, 嘿嘿, 我们现在用 render()
每次自己看东西到这种就感觉很 ******, 但是好在这样是一个理解的过程
来, 再改 views.py
- def index(request):
- latest_question_list = Question.objects.order_by('-pub_date')[:5]
- context = {'latest_question_list': latest_question_list}
- return render(request, 'polls/index.html', context)
但是注意了, 这里几个不同的方法, 最终实际上都是一个 HttpResponse 对象, 是不是一种万物归一的感觉, 茅塞顿开
然后刘老师讲了异常处理, 这里也就是 404 的而已
开始是这样的(views.py):
- from django.http import Http404
- from django.shortcuts import render
- from .models import Question
- # ...
- def detail(request, question_id):
- try:
- question = Question.objects.get(pk=question_id)
- except Question.DoesNotExist:
- raise Http404("Question does not exist")
- return render(request, 'polls/detail.html', {'question': question})
然后是这样的:
- from django.shortcuts import get_object_or_404, render
- from .models import Question
- # ...
- def detail(request, question_id):
- question = get_object_or_404(Question, pk=question_id)
- return render(request, 'polls/detail.html', {'question': question})
一 jio 吧 try except 踢到九霄云外, 就用而言, 请你直接上高级的.
好的, 现在再去写一个 detail 的模板
看看视图中 detail 方法 (函数) 中的语句, 从数据库表(类)Question model 对应的表中取到主键等于传入 question_id 的 Question 对象并把它字典形式传入并渲染模板
detail.HTML 放在哪里就不用说了, 都是 polls 的模板
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- detail
- </title>
- </head>
- <body>
- <h1>
- {{ question.question_text }}
- </h1>
- <ul>
- {% for choice in question.choice_set.all %}
- <li>
- {{ choice.choice_text }}
- </li>
- {% endfor %}
- </ul>
- </body>
- </HTML>
由于在写 model 时候说过的, 这里的 Question 和 Choice 是有所关联的, 两个类就可以相互去做一些查询, 算是 django 的骚操作了, 所以当把 question 传过来后, detail.HTML 就开始疯狂的使用他, 而遍历数据却在 choice 的表中
这就很有意思了
那么效果是:
删除模板中硬编码的 urls
什么叫硬编码的 urls? 打个比方, 有一波人卖房子的人, 另一波叫卖房子的人, 卖房子原来自己联系买家, 结果这些人又很恶心, 一会儿想买一会儿不想买, 搞来搞去, 同一个买家找人找的快费劲死, 后来这些卖家全干掉, 交给中介去高了, 对于买家来说, 只要应付中介就完事了..... 说了好长
这里的硬核 url 就是那种耐冲击性很差的存在, 这个词好像是在水污染控制工程里面第一次学, 某些东西无法抵抗水质的突变
当我们的路径发生变化的时候, 如果 HTML 页面上直接填写的是页面路径, 那就需要重新修改这个地方, 一处改一个, 一万处就凉凉, 所以这里要用别名
对比一下 index 中的两句:
- {# 被注释 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>#}
- <li><a href="{% url'detail'question.id %}">{{ question.question_text }}</a></li>
在 urls.py 中我们有写过 name="" 这个地方, 这里就是起别名, 最终用到 HTML 这里很舒服, 这是要修改的地方, 这样的方法是很提高效率的
url 命名空间:
在 polls/urls.py 中加入变量 app_name='polls'
那么此时再对 index.HTML 文件中的那个超链接地址进行修改吧, 指明, 是 polls 的 detail.
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Title
- </title>
- </head>
- <body>
- {% if latest_question_list %}
- <ul>
- {% for question in latest_question_list %} {#
- <li>
- <a href="/polls/{{ question.id }}/">
- {{ question.question_text }}
- </a>
- </li>
- #}
- <li>
- <a href="{% url'polls:detail'question.id %}">
- {{ question.question_text }}
- </a>
- </li>
- {% endfor %}
- </ul>
- {% else %}
- <p>
- No polls are available.
- </p>
- {% endif %}
- </body>
- </HTML>
- from django.urls import path
- from . import views
- app_name = 'polls'
- urlpatterns = [
- path('', views.index, name='index'),
- # ex:/polls/5
- path('<int:question_id>/', views.detail, name='detail'),
- # ex:/polls/5/results
- path('<int:question_id>/results/', views.results, name='results'),
- # ex:/polls/5/vote/
- path('<int:question_id>/vote/', views.vote, name='vote'),
- # 添加新的单词'specifics'有了中介之后这里就是改了也无妨
- path('specifics/<int:question_id>/', views.detail, name='detail'),
- ]
两点了睡了睡了
使用 pycharm 开发 Web--django2.1.5(四)视图和模板相关
来源: http://www.bubuko.com/infodetail-3098936.html