第一个django应用程序_part3(代码片段)

author author     2022-11-21     525

关键词:

一、概述

此文延续第一个Django应用程序part2

官方文档:https://docs.djangoproject.com/en/1.11/intro/tutorial03/

view是Django应用程序中的“类”网页,它通常使用一个特定的函数提供服务,并且具有一个特定的模版。例如在博客应用程序中,kennel有以下视图:

  • 博客首页-显示最新的几个条目。
  • 博客“详细”页面 --单篇博客的固定链接页面。
  • 基于年份的存档页面-显示给定年份的所有月份。
  • 基于月份的存档页面-显示所有日期与给定月份的条目。
  • 基于日的存档页面-显示给定日期中的所有条目。
  • 评论动作-处理对给定条目的发布评论。

在我们的polls应用程序中,我们将拥有以下四个视图:

  • 问题“索引”页面-显示最新的几个问题。
  • 问题“详细信息”页面detail-显示单个Question的具体内容,不显示该议题的当前投票结果,而是提供一个投票的表单。
  • 问题“结束”页面detail -显示特定问题的结果。
  • 投票功能vote-处理特点问题中特定选择的投票。

在Django中,网页和其它内容有视图提供。每个视图都由一个简单的Python函数(或基于类视图的方法)来表示。Django将通过检查所请求的URL(确切的说,域名后的URL部分),来选择一个视图。

平日你上网时,可能会遇到像 “ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B”这样 "优美" 的URL。很高兴是,Django允许我们使用更加优雅的URL模式。

网址格式只是URL的一般形式,例如:/newsarchive/<year>/<month>/

要从URL到视图,Django使用所谓的“URLconfs”。URLconf将URL模式(描述为正则表达式)映射到视图。

Django.urls更多信息:https://docs.djangoproject.com/en/1.11/ref/urlresolvers/#module-django.urls

二、添加视图

现在我们再添加一些视图到polls/views.py。

def index(request):
    return HttpResponse("Hello,world.You\'re at the polls index.")

def detail(request,question_id):
    return HttpResponse("Your\'re lokking 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))

通过添加以下url()调用,将这些新views连接到polls/urls.py模块中。

from django.conf.urls import url
from . import views


urlpatterns = [
    #ex: /polls/
    url(r\'^$\',views.index,name=\'index\'),
    #ex: /polls/5/
    url(r\'^(?P<question_id>[0-9]+)/$\',views.detail,name=\'detail\'),
    #ex: /polls/5/results/
    url(r\'^(?P<question_id>[0-9]+)/results/$\',views.results,name=\'results\'),
    #ex: /polls/5/vote/
    url(r\'^(?P<question_id>[0-9]+)/vote/$\',views.vote,name=\'vote\'),
]

在浏览器中查看"/polls/34/"。它将运行detail()方法,并显示您在URL中提供的任何ID(Your\'re lokking at question 34.)。

例如:"/polls/34/results/"。浏览器显示结果:You\'re looking at the results of question 34.

"/polls/34/vote/"。浏览器显示结果:You\'re voting on question 34.

当有人从您的网站请求一个页面-例如"/polls/34/"时,Django将加载mysite.urls Python模块,因为它被ROOT_URLCONF设置指向。它找到名为urlpatterns的变量,并按照顺序遍历正则表达式。在\'^polls/\'找到匹配后,它将取消匹配的文本("polls/"),并发送剩余的文本-"34/"-到\'polls.urls\'URLconf进行进一步处理。它匹配r\'^(<?Pquestion_id>[0-9]+)/$\',请求detail()视图的结果就像下面一样:

detail(request=<HttpRequest object>, question_id=\'34\')

question_id = \'34\'部分来自(?P<question_id>[0-9]+)。使用模式周围的括号"捕获"该模式匹配的文本,并将其作为参数发送给视图函数;?P<question_id>定义待处理的question_id;

[0-9]+是匹配数字的正则表达式。

由于其网址格式是正则表达式,所以您可以对他们做什么,实际上没有限制。而且不需要添加URL cruft,例如.html-除非你想,在这种情况下你可以这样做:

url(r\'^polls/latest\\.html$\', views.index),

但是,不要这样做。太愚蠢了。

三、编写实际执行某些操作的视图

每个视图负责执行以下两项操作之一:返回包含所请求页面内容的HttpResponse对象,或引发例如Http404等异常。

你的views可以从数据库读取记录。它可以使用Django的模版系统,也可以使用第三方Python模版系统。它可以生成PDF文件,输出XML,随时创建一个ZIP文件,任何你想要的,使用任何你想要的Python库。

Django想要的就是这个HttpResponse。或者是一个例外。

这是一个新的index()视图,它显示系统中最新的5个polls问题,用逗号分隔,根据发布日期:

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

这里有一个问题:页面的设计在视图中是硬编码。如果要更改页面的样式,则必须编辑此Python代码。所以让我们使用Django模版系统通过创建视图可以使用的模版来将设计与Python分开。

首先,在polls目录中创建一个名为templates的目录。Django会在那里寻找模版。

您的项目的TEMPLATES设置描述了Django如何价值和呈现模版。默认设置文件匹配APP_DIRS选择设置为True的DjangoTemplates后端。按照惯例DjangoTemplates在INSTALLES_APPS中查找"templates"子目录。

在刚刚创建的模版目录中,创建另一名为polls的目录,并在其中创建一个名为index.html的文件。换句话说,你的模版应该在polls/templates/polls/index.html。由于app_directories模版加载器的工作原理如上所述,您可以将Django中此模版简单地称为polls/index.html。

  • 模版命名空间
现在,我们可以直接放在polls/templates中(而不是创建另一个polls子目录),但是它会其实是一个糟糕的主意。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 %

现在让我们使用模版更新polls/views.py中的index视图:

from django.http import HttpResponse
from .models import Question
from django.template import loader



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))

该代码加载名为polls/index.html的模版,并传递一个上下文。上下文是将模版变量名名称映射到Python对象的字典。

通过将浏览器指向"/polls/"来加载页面,您应该看到包含第一个Django应用程序part2 中的"What\'s up"问题的项目符号列表。链接指向问题的详细页面。

四、快捷方式:render()

通常的做法是用上下文加载模版,然后返回渲染后的HttpResponse对象。Django提供了一个快捷方式。这是完整的index()视图,重写:

from django.shortcuts import render
from .models import Question


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)

请注意,一旦我们在所有这些视图中完成了这些操作,我们就不再需要导入, loader并且HttpResponseHttpResponse如果您仍然具有,和的存根方法detail, 您将需要保留)。

render()函数将请求对象作为其第一个参数,模版名作为第二个参数,并将字典作为其可选的第三个参数。它返回使用给定上下文呈现的给定模版的HttpResponse对象。

五、触发404错误

现在,我们来处理问题详细视图(question detail view)-显示给定投票的问题文本的页面,以下是视图:

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)

如果请求的ID的问题不存在,则该视图引发了Http404异常。

我们将在稍后讨论可以放在该polls/detail.html模板中的内容,但如果您想快速获得上述示例的工作方式,则只需包含以下内容的文件:

polls/templates/polls/detail.html

 question 

六、快捷方式:get_object_or_404()

如果对象不存在,使用get()触发Http404是一个很常见的情况。Django提供了一个快捷方式。这里是detail()视图,重写如下:

  • polls/views.py
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)

get_object_or_404()函数将Django模型作为其第一个参数和任意数量的关键字参数,它传递给模型管理器的get()函数。如果对象不存在,它会引发Http404。

  • 提示:
为什么使用函数get_object_or_404()而不是自动捕获ObjectDoesNotExist更高级别的异常,或者使用模型API Http404而不是ObjectDoesNotExist?
因为那会将模型图层耦合到视图图层。Django最重要的设计目标之一是保持松耦合。django.shortcuts模块引入了一些受控耦合。

 还有一个get_list_or_404()函数,除了使用filter()而不是get()之外,它可以像get_object_or_404()。如果列表为空,它会触发Http404。

七、模版系统

返回到我们的polls应用程序的detail()视图。给定上下文变量question,以下是polls/detail.html模版的样子:

<h1> question.question_text </h1>
<ul>
% for choice in question.choice_set.all %
    <li> choice.choice_text </li>
% endfor %
</ul>

模版系统使用点查找语法来访问变量属性。在 question.question_text 的示例中,首先Django会在对象question上查找。否则,它会尝试一个属性查找-在这种情况下可以工作。如果属性查找失败,它将尝试列表索引查找。

方法调用发生在% for %循环:question.choice_set.all被解释为Python代码question.choice_set.all(),它返回一个Choice对象的迭代,适用于% for %标签。

删除模版中的硬编码网址

当我们在polls/index.html模版中写入一个question的链接时,链接部分硬件编码如下:

<li><a href="/polls/ question.id /"> question.question_text </a></li>

这种硬编码,紧密耦合的方法的问题是,在具有大量模版的项目上更改URL变得具有挑战性。但是,由于您在polls.urls模块中的url()函数中定义了name参数,因此可以删除对url配置中定义的特定URL路径的依赖使用% url %模版标签:

<li><a href="% url \'detail\' question.id %"> question.question_text </a></li>

这种方式是通过查找polls.urls模块中指定的URL定义。您可以看到下面定义了"detail"的URL名称:

url(r\'^(?P<question_id>[0-9]+)/$\', views.detail, name=\'detail\'),

如果您想将polls详细信息视图的URL更改为其它内容,可能polls/specifics/12/不是在模版(或模版)中进行,而是将其更改为polls/urls.py:

url(r\'^specifics/(?P<question_id>[0-9]+)/$\', views.detail, name=\'detail\'),

名称空间URL名称

在项目中只有一个应用程序polls。在实际的Django项目中,可能有五、十、二十个甚至更多个应用。Django如何区分他们之间的URL名称?例如:polls应用程序具有detail视图,同一项目中的应用程序也可能是一个博客。当使用% url %时,Django会如何知道哪个应用程序视图为url创建模版标签?

解决的方法是为您的URLconf添加命名空间。在polls/url.py文件中,继续添加一个app_name来设置应用程序命名空间:

from django.conf.urls import url
from . import views


urlpatterns = [
    url(r\'^$\',views.index,name=\'index\'),
    url(r\'^(?P<question_id>[0-9]+)/$\',views.detail,name=\'detail\'),
    url(r\'^(?P<question_id>[0-9]+)/results/$\',views.results,name=\'results\'),
    url(r\'^(?P<question_id>[0-9]+)/vote/$\',views.vote,name=\'vote\'),
]

现在更改您的polls/index.html模版:

polls/templates/polls/index.html

<li><a href="% url \'detail\' question.id %"> question.question_text </a></li>

指向带有命名空间的detail视图:

polls/templates/polls/index.html

<li><a href="% url \'polls:detail\' question.id %"> question.question_text </a></li>

 

django编写您的第一个django应用三(代码片段)

...多视图polls/views.py。这些视图略有不同,因为它们采用了一个参数:  polls.urls通过添加以下path()调用将这些新视图连接到模块中 :  当有人从您的网站请求页面时,例如“/polls/34/”,Django将加载mysite.urlsP... 查看详情

django编写您的第一个django应用三(代码片段)

...多视图polls/views.py。这些视图略有不同,因为它们采用了一个参数:  polls.urls通过添加以下path()调用将这些新视图连接到模块中 :  当有人从您的网站请求页面时,例如“/polls/34/”,Django将加载mysite.urlsP... 查看详情

第四周练习part3(代码片段)

列表生成式#列表生成式a=[i*2foriinrange(10)]print(a)deffunc(j):j=j/2returnjb=[func(i)foriinrange(100)]foriinb:print(i)c=(i*2foriinrange(1000))foriinc:ifi<530:print(i)d=(i*3foriinrange(10))#只有一个next方法,用的不多,一般都 查看详情

django学习路30_view中存在重复名时,取第一个满足条件的(代码片段)

在settings中添加INSTALLED_APPS=[‘django.contrib.admin‘,‘django.contrib.auth‘,‘django.contrib.contenttypes‘,‘django.contrib.sessions‘,‘django.contrib.messages‘,‘django.contrib.staticfiles‘,‘app.apps.AppCon 查看详情

django学习路30_view中存在重复名时,取第一个满足条件的(代码片段)

在settings中添加INSTALLED_APPS=[‘django.contrib.admin‘,‘django.contrib.auth‘,‘django.contrib.contenttypes‘,‘django.contrib.sessions‘,‘django.contrib.messages‘,‘django.contrib.staticfiles‘,‘app.apps.AppCon 查看详情

搭建第一个django网站(代码片段)

1:搭建第一个Django网站我的环境安装了anaconda3.X,已经自带了django框架。C:Usershe>condalistDjango#packagesinenvironmentatF:aiinstallAnaconda3:##NameVersionBuildChanneldjango2.2.3pypi_0pypi1.手动创建第一个djangdo项目##1:切换目录pushdF: 查看详情

第四周:卷积神经网络part3(代码片段)

一、代码练习完善HybridSN高光谱分类网络HybridSN高光谱分类S.K.Roy,G.Krishna,S.R.Dubey,B.B.ChaudhuriHybridSN:Exploring3-D–2-DCNNFeatureHierarchyforHyperspectralImageClassification,IEEEGRSL2020这篇论文构建了一个混合网络解决高光谱图像分类问题,首先用3D卷 查看详情

2-第一个django程序(代码片段)

第一个Django程序从本章节开始将通过实现一个投票应用程序,来让用户逐步的了解Django。这个程序由两步分组成:公共站点,允许用户访问进行投票,和查看投票。站点管理,允许添加,删除,修改投票信息。1、创建项目本文... 查看详情

第一个django程序(代码片段)

【windows】django-adminstartproject djprocd djpropythonmanage.pystartappapp_test1 /djpro/seting.py增加  /djpro/urls.py增加 /app_test1/views.py增加fromdjango.httpimportHttpRespons 查看详情

django_测试功能(代码片段)

开始写我们的第一个测试首先得有个Bug幸运的是,我们的 polls 应用现在就有一个小bug需要被修复:我们的要求是如果Question是在一天之内发布的, Question.was_published_recently() 方法将会返回 True ,然而现在这... 查看详情

django教程(代码片段)

...目的是要实现简单快捷的网站开发。from 编写你的第一个Django应用,第1部分.thefirstDjangostartProject1.createourproject"mysite"让我们看看 startproject 创建了些什么:mysite/manage.pymysite/__init__.pysettings.pyurls.pyasgi.pywsgi.py这些目录和文... 查看详情

编写你的第一个django应用程序(代码片段)

本教程中,我们将带领你创建一个基本的投票应用。它包含两部分:一个公开站点,允许人们查看投票并对它们投票。一个管理后台站点,允许你添加、更改和删除投票。我们假设你已经安装好Django。你可以通过在shell提示符(... 查看详情

自定义django-admin命令(代码片段)

...需要定时清空某篇文章下面的评论,一种解决方案就是写一个django-admin命令,再写一个运行该命令的独立脚本,最后通过crontab服务,定时执行该脚本。下面,我们将为教程最开始的第一个Django应用中的polls应用编写一个自定义的... 查看详情

django创建第一个模块应用(代码片段)

...下正——老子《道德经》本章内容创建应用(app)开发第一个视图(View)URL访问配置的嵌套(urls)1.创建项目的子模块应用上一节内容中,我们创建了一个django项目mysite/,在项目的骨架的基础上,我们再创建基于项目的一个子... 查看详情

s10_part3_django_basic.md

```https://www.bilibili.com/video/av24702867/?p=337```[TOC]#django安装```mkdir-p~/PycharmProjects/project/Django2.0cd~/PycharmProjects/project/Django2.0virtualenvmysite-envsourcemysite-env/bin/activatep 查看详情

2编写第一个django应用(投票应用),第二部分简要过程(代码片段)

上一章https://blog.51cto.com/yht1990/2382801本章节官网详细参考:https://docs.djangoproject.com/zh-hans/2.1/intro/tutorial02/1、配置pymysql代替MySQLdb在需要的项目中(D:mysitepolls下的init.py)添加如下内容importpymysqlpymysql.install_a 查看详情

django_04_视图(代码片段)

...进行两步操作1.定义视图2.配置URLconf1.定义视图视图就是一个Python函数,被定义在views.py中视图的第一个参数是HttpRequest类型的对象reqeust,包含了所有请求的信息视图必须返回HttpR 查看详情

开始第一个django(代码片段)

安装完django1、创建项目guest项目  django-adminstartprojectguest2、进入项目  cdguest3、查看manage所提供的命令  pythonmanage.py4、创建sign应用  pythonmanage.pystartappsign    5、运行项目  pythonmanage.pyrunserver6、ps 查看详情