第18章_Django入门——【3.创建网页主页】与【4.创建网页其他页面】

本文详细介绍使用Django框架创建网页的过程,包括定义URL、编写视图和模板,以及如何通过继承实现网页布局的复用。文章还展示了如何展示数据库中的数据,如主题和条目,以及如何设置链接进行页面跳转。

《Python编程从入门到实践》学习笔记——Django
内容包括【3.创建网页主页】与【4.创建网页其他页面】

使用Django创建网页通常分三个阶段:
①定义URL(learning_logs/urls.py)
②编写视图(learning_logs/views.py)
③编写模板(learning_logs/templates/learning_logs/XXXX.html)

在下面创建主页和其它页面都需要按照这三个步骤。

写在前面:代码块里很多解释性的“废话”是我自己加的,为了便于我自己理解

【创建网页:学习笔记主页】

[映射URL](定义URL)

主页URL是用户访问项目的基础URL,当前的基础URL(http://localhost:8000)返回默认的Django网站,现在我们需要将这个基础URL映射到“学习笔记”的主页。
1.打开主项目文件夹learning_log内的urls.py,此时内容如下

from django.contrib import admin
from django.urls import path  #这里和书上不一样,书上是include,url
urlpatterns = [
    path('admin/', admin.site.urls), #这里和书上不一样,书上是url
]

我们需要包含learning_logs的URL
所以修改为

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include  #增加导入url和include
urlpatterns = [
    path('admin/', admin.site.urls),
	#书上是url(r'',include('learning_logs.urls',namespace='learning_logs')), 根据https://blog.csdn.net/czw0723/article/details/80761231修改后才没出错
    url(r'',include(('learning_logs.urls',"learning_logs"),namespace='learning_logs')), #实参namespace使得learning_logs的URL同项目中的其它URL区分开来,便于项目扩展
]

2.在文件夹learning_logs中创建一个urls.py文件
内容为

"""定义learning_logs的URL模式"""
from django.conf.urls import url
#from django.urls import path  如果下面不用url而用path就导入path
from . import views  #从该urls.py所在文件夹导入模块views
#变量urlpattern是一个列表,包含可在应用程序learning_logs中请求的网页
urlpatterns=[   
	#主页
	#实际的URL模式是一个对函数url的调用,这个函数接受三个实参
	"""第一个实参r'^$'是一个正则表达式,它定义了Django可查找的模式。"""
	#正则表达式r'^$':r让Python将接下来的字符串看作原始字符串,引号指明其开始与结束处,脱字符^让Python查看字符串开头,美元符号$让Python查看字符串末尾
	#综上,正则表达式r'^$'让python查找开头和末尾之间没有任何东西的URL
	#由于Python忽略项目的基础URL(http://localhost:8000/),因此这个正则表达式与基础URL匹配,而和其他URL都不匹配
	#如果请求的URL不与任何URL匹配,则返回错误页面
	"""第二个实参view.index指定了要调用的视图函数"""
	#请求的URL与前述正则表达式匹配时,Django将会调用view.index,该视图内容需要编写
	"""第三个实参name='index'将这个URL模式的名称指定为index,以后可以引用这个名称index"""
	url(r'^$',views.index,name='index'),
]

[编写视图]

视图函数接受请求中的信息,准备好提供生成网页需要的数据
3.打开learning_logs中的views.py,注:该文件是在执行python manage.py startapp时自动生成的
此时内容为

from django.shortcuts import render
# Create your views here.

在后面添加

def index(request):  #前面提到了views.index,所以这里定义的函数是index(),并将URL的请求传递给该函数,该函数调用render()
	"""学习笔记的主页"""
	return render(request,'learning_logs/index.html') #提供给render()两个实参:原始请求对象和learning_logs下的index.html这个能用来创建网页的模板,该模板需要编写

[编写模板]

4.在learning_logs下新建文件夹templates,在templates下新建文件夹learning_logs,在learning_logs下新建文件index.html
5.打开index.html
编写内容

<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>

6.打开http://localhost:8000,此时不会显示默认的Django网页而会是index.html的内容
我还将index.html中的内容改成下面这样试试了,因为忘记了HTML怎么写的

<html>
<head>
<title>index</title>
</head>
<body>
<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
</body>
</html>

【创建其他网页】

[模板继承]

1.创建父模板base.html并存储在index.html所在目录中。该文件要包含所有页面的元素。
内容为
#创建一个包含项目名的段落,它是一个到主页的链接

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a>  #模板标签{%%}生成要在网页中显示的信息,这里生成一个URL,匹配learning_logs/urls.py中定义的名为index的URL模式。这里的learning_logs是一个命名空间,learning_log/urls.py里有讲到。
</p>
#一对块标签,块名content,是一个占位符,其信息由子模板决定。这里可以多放几个块来预留空间
{% block content %}{% endblock content %} 

2.重新编写子模板index.html,让它继承父模板base.html
内容为

{% extends "learning_logs/base.html" %} #明确继承的父模板是哪个
#在块里放不是从父模板继承的内容,也就是放当前网页特有的内容
{% block content %} 
  <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
{% endblock content %}

[显示所有主题的页面]

1.定义URL

定义显示所有主题的页面的URL为http://localhost:8000/topics/
修改learning_logs/urls.py为

"""定义learning_logs的URL模式"""
from django.conf.urls import url
#from django.urls import path
from . import views
urlpatterns=[
	#主页
	url(r'^$',views.index,name='index'),
	
	#显示所有的主题
	url(r'^topics/$',view.index,name='topics')  ----->新加的,匹配有topics的URL:http://localhost:8000/topics/
]
2.编写视图

views.py视图接受请求中的信息,准备好提供生成网页需要的数据
打开views.py,修改为

from django.shortcuts import render
from .models import Topic  ----->新加的,从当前目录下的models.py导入Topic模型
# Create your views here.
def index(request):
	"""学习笔记的主页"""
	return render(request,'learning_logs/index.html')
	
def topics(request):     #这里的topics对应上面urls.py里的name='topics'
	"""显示所有的主题"""
	topics=Topic.objects.order_by('date_added')   #按date_added排序,返回的查询集存储在topics
	context={'topics':topics}    #定义一个字典,键是在模板中用来访问数据的名称,值是要发送给模板的数据
	return render(request,'learning_logs/topics.html',context) #将request、模板路径、变量context传递给render()
3.编写模板

显示所有主题的页面的模板topics.html需要接受字典context
新建topics.html在index.html所在目录
内容为

#继承base.html
{% extends "learning_logs/base.html" %} 
#开始定义content块
{% block content%}
  <p>Topics</p>
  #在HTML中,项目列表被称为无序列表,用标签<ul></ul>表示
  <ul>
    {% for topic in topics %----->类似for循环的标签,遍历context中的列表topics
	  <li>{{topic}}</li>  ----->双花括号表示变量名,<li></li>表示一个项目列表项
    {% empty%}  ----->指出列表topics为空时怎么办
	  <li>No topics have been added yet.</li> ----->打印该消息
    {% endfor %}  ----->模板中必须用它表示for循环结束
  </ul>
{% endblock content%}

4.修改父模板base.html,使之包含显示所有主题的页面的链接
打开base.html,修改为

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a> -  ----->加了一个连字符-,样子好看点
  <a href="{% url 'learning_logs:topics' %}">Topics</a>  ----->添加链接,匹配名为topics的URL模式
</p>
{% block content %}{% endblock content %}

5.刷新浏览器当前主页,查看变化。

[显示特定主题的页面]

1.URL模式(定义URL)

打开learning_logs/urls.py,修改为

"""定义learning_logs的URL模式"""
from django.conf.urls import url
#from django.urls import path
from . import views
urlpatterns=[
	#主页
	url(r'^$',views.index,name='index'),
	#显示所有的主题
	url(r'^topic/$',views.topics,name='topics'),
	#特定主题的详细页面
	"""r'^topics/(?P<topic_id>\d+)$'"""
	#r能将字符串视为原始字符串,正则表达式包含在引号内
	#(?P<topic_id>\d+)与包含在//里的整数匹配,并将这个整数存储在一个叫topic_id的实参中。
	#()捕获URL中的值,?P<topic_id>将匹配到的值存储在topic_id中
	#\d+与包含在两个斜杠内的任何数字都匹配,不管数字是几位数
	"""发现匹配URL后,调用views.py里的函数topic(),并将topic_id传递给它"""
	url(r'^topics/(?P<topic_id>\d+)/$',views.topic,name='topic'),
]
2.编写视图

打开view.py,在最后面添加函数

def topic(request,topic_id):   #接受正则表达式(?P<topic_id>\d+)捕获的值,并存储到topic_id中
	"""显示单个主题及其所有的条目"""
	topic=Topic.objects.get(id=topic_id)   #获取指定主题
	entries=topic.entry_set.order_by('-date_added')  #获取和上面获取主题相关的条目,并按date_added排序,-表示降序,先显示最

近的
	context={'topic':topic,'entries':entries}  #将前面获取的主题和条目存储在context里面
	return render(request,'learning_logs/topic.html',context)  #将context发送给模板topic.html
3.编写模板

显示主题名称和条目内容
新建topic.html,内容为

{% extends 'learning_logs/base.html'%}  #继承base.html
{% block content%}   
  <p>Topic:{{topic}}</p>   #显示当前主题
  <p>Entries</p> 
  <ul>    #项目列表
  {% for entry in entries %}     #遍历条目
    <li>
	  <p>{{entry.date_added|date:'M d, Y H:i'}}</p>   #显示时间戳 月 日,年 时间
	  <p>{{entry.text|linebreaks}}</p>    #显示entry的所有内容。过滤器linebreaks将包含换行符的长条目转换成浏览器能够理解的格式
    </li>
  {% empty %}
    <li>
	  There are no entries for this topic yet.
    </li>
  {% endfor %}
  </ul>
{% endblock content %}

4.将显示所有主题的页面中的每个主题都设置为链接
打开topics.html,修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值