Django 文档 学习第一天
urls.py的使用
让我们开始编写第一个视图吧。打开 polls/views.py,把下面这些 Python 代码输入进去:
polls/views.py from django.http import HttpResponse
def index(request):
return HttpResponse(“Hello, world. You’re at the polls index.”) 这是 Django 中最简单的视图。如果想看见效果,我们需要将一个 URL 映射到它——这就是我们需要 URLconf 的原因了。为了创建 URLconf,请在 polls 目录里新建一个 urls.py 文件。你的应用目录现在看起来应该是这样:
polls/
init.py
admin.py
apps.py
migrations/
init.py
models.py
tests.py
urls.py
views.py 在 polls/urls.py 中,输入如下代码:polls/urls.py from django.urls import path
from . import views
urlpatterns = [
path(”, views.index, name=’index’), ] 下一步是要在根 URLconf 文件中指定我们创建的 polls.urls 模块。在 mysite/urls.py 文件的 urlpatterns 列表里插入一个 include(), 如下:mysite/urls.py from django.contrib import admin from django.urls
import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls), ]
函数 include() 允许引用其它 URLconfs。每当 Django 遇到 :func:django.urls.include 时,它会截断与此项匹配的 URL 的部分,并将剩余>的字符串发送到
URLconf 以供进一步处理。我们设计 include() 的理念是使其可以即插即用。因为投票应用有它自己的 URLconf( polls/urls.py
),他们能够被放在 “/polls/” , “/fun_polls/”
,”/content/polls/”,或者其他任何路径下,这个应用都能够正常工作。何时使用 include()
当包括其它 URL 模式时你应该总是使用 include() , admin.site.urls 是唯一例外。
你现在把 index 视图添加进了 URLconf。可以验证是否正常工作,运行下面的命令:
$ python manage.py runserver 用你的浏览器访问
http://localhost:8000/polls/,你应该能够看见 “Hello, world. You’re at the
polls index.” ,这是你在 index 视图中定义的。
这是从https://docs.djangoproject.com/zh-hans/2.0/intro/tutorial01/
copy过来一段 记录一下
当包括其它 URL 模式时你应该总是使用 include() , admin.site.urls 是唯一例外。
path() 参数: name
为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。每个视图必须要做的只有两件事:返回一个包含被请求页面内容的 HttpResponse 对象,或者抛出一个异常,比如 Http404 。至于你还想干些什么,随便你。
你的视图可以从数据库里读取记录,可以使用一个模板引擎(比如 Django 自带的,或者其他第三方的),可以生成一个 PDF
文件,可以输出一个 XML,创建一个 ZIP 文件,你可以做任何你想做的事,使用任何你想用的 Python 库。Django 只要求返回的是一个 HttpResponse ,或者抛出一个异常。
到这里对urls里的URLpattern 的作用 以及对每个view的该做的事情就有所了解了 感觉 前端和后端的数据交换的唯一接口是URL 通过URL来调用后端的程序 而且 可以在URL里传递参数给后台 从而调用有参数的函数
例如以下的一个例子:
编写更多视图 现在让我们向 polls/views.py 里添加更多视图。这些视图有一些不同,因为他们接收参数:
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)
把这些新视图添加进 polls.urls 模块里,只要添加几个 url() 函数调用就行:
polls/urls.py 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'), ]
然后看看你的浏览器,如果你转到 “/polls/34/” ,Django 将会运行 detail() 方法并且展示你在 URL 里提供的问题
ID。再试试 “/polls/34/vote/” 和 “/polls/34/vote/” ——你将会看到暂时用于占位的结果和投票页。当某人请求你网站的某一页面时——比如说, “/polls/34/” ,Django 将会载入 mysite.urls 模块,因为这在配置项
ROOT_URLCONF 中设置了。然后 Django 寻找名为 urlpatterns 变量并且按序匹配正则表达式。在找到匹配项
‘polls/’,它切掉了匹配的文本(”polls/”),将剩余文本——”34/”,发送至 ‘polls.urls’ URLconf
做进一步处理。在这里剩余文本匹配了 ‘/’,使得我们 Django 以如下形式调用 detail():detail(request=, question_id=34) question_id=34 由
匹配生成。使用尖括号“捕获”这部分 URL,且以关键字参数的形式发送给视图函数。上述字符串的
:question_id> 部分定义了将被用于区分匹配模式的变量名,而 int: 则是一个转换器决定了应该以什么变量类型匹配这部分的 URL
路径。为每个 URL 加上不必要的东西,例如 .html ,是没有必要的。不过如果你非要加的话,也是可以的:
path(‘polls/latest.html’, views.index), 但是,别这样做,这太傻了。
举个例子
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)
# Leave the rest of the views (detail, results, vote) unchanged
这里就体现了Django的模板的作用了 Question 的类是定义好的一个对象
以及 .join 的用法 就是.split 的逆用法
以及[a for a in a_list ]的简便写法
模板命名空间
虽然我们现在可以将模板文件直接放在 polls/templates 文件夹中(而不是再建立一个 polls子文件夹),但是这样做不太好。Django
将会选择第一个匹配的模板文件,如果你有一个模板文件正好和另一个应用中的某个模板文件重名,Django 没有办法 区分 它们。我们需要帮助
Django 选择正确的模板,最简单的方法就是把他们放入各自的 命名空间 中,也就是把这些模板放入一个和 自身 应用重名的子文件夹里。
Django 的模板文件的推荐组织形式 命名空间
{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{
{ question.id }}/">{
{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
需要注意的有两点 一个是 先判断是否存在 另一个 是 for in 加上
href =”/polls/{ { .id}}”的构成形式 html写连接的形式
不过 有一点问题 就是 polls 是硬编码 不好更改
这里就 体现了name的作用 因为你在 polls.urls 的 url() 函数中通过 name 参数为 URL 定义了名字,你可以使用 {% url %} 标签代替它:
<li><a href="{% url 'detail' question.id %}">{
{ question.question_text }}</a></li>
这个标签的工作方式是在 polls.urls 模块的 URL 定义中寻具有指定名字的条目。你可以回忆一下,具有名字 ‘detail’ 的 URL 是在如下语句中定义的:
如果你想改变投票详情视图的 URL,比如想改成 polls/specifics/12/ ,你不用在模板里修改任何东西(包括其它模板),只要在 polls/urls.py 里稍微修
改一下就行。
好了 引入了命名空间 重复的问题也就解决了
说的很详细了 不多说了
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from .models import Choice, Question
# ...
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
另一个案例
关于重定位问题 以及 request.post.get()
还可以考虑通用视图 就是Django已经内部实现的模板 通过继承来构造自己的模板
我们在这里使用两个通用视图: ListView 和 DetailView 。这两个视图分别抽象“显示一个对象列表”和“显示一个特定类型对象的详细信息页面”这两种概念。
每个通用视图需要知道它将作用于哪个模型。 这由 model 属性提供。
DetailView 期望从 URL 中捕获名为 “pk” 的主键值,所以我们为通用视图把 question_id 改成 pk 。
默认情况下,通用视图 DetailView 使用一个叫做 /_detail.html 的模板。在我们的例子中,它将使用 “polls/question_detail.html” 模板。template_name 属性是用来告诉 Django 使用一个指定的模板名字,而不是自动生成的默认名字。 我们也为 results 列表视图指定了 template_name —— 这确保 results 视图和 detail 视图在渲染时具有不同的外观,即使它们在后台都是同一个 DetailView 。
类似地,ListView 使用一个叫做 /_list.html 的默认模板;我们使用 template_name 来告诉 ListView 使用我们创建的已经存在的 “polls/index.html” 模板。
在之前的教程中,提供模板文件时都带有一个包含 question 和 latest_question_list 变量的 context。对于 DetailView , question 变量会自动提供—— 因为我们使用 Django 的模型 (Question), Django 能够为 context 变量决定一个合适的名字。然而对于 ListView, 自动生成的 context 变量是 question_list。为了覆盖这个行为,我们提供 context_object_name 属性,表示我们想使用 latest_question_list。作为一种替换方案,你可以改变你的模板来匹配新的 context 变量 —— 这是一种更便捷的方法,告诉 Django 使用你想使用的变量名。
OK的就这样子了