Skip to main content

【开发企业官网】9.新闻列表页和详情页模块实现

现在我们已经添加了不同分类的新闻,接下来需要将它们显示在我们的页面上。在前端页面中,通常会有一个新闻的列表页和一些新闻的详情页。因此,我们需要设置两个URL,一个用于列表页,一个用于新闻详情页。在我们的配置文件中在config文件夹下urls.py文件中,我们直接设置这两个路径。在路径中设计“news/list”来表示列表页还需要一个url来表示news详情页。由于都以“news”开头,所以我们将它们放到了news应用(文件夹)下,在config文件夹下urls.py文件中使用include函数导入相应的URL配置。代码如下:

from django.contrib import admin
from django.urls import path, include
from mysite import views

# 定义URL模式列表
urlpatterns = [
# 首页路径,指向视图函数 index
path('', views.index),
# 新闻相关路径,包含 news 应用的 URL 配置
path('news/', include('news.urls')),
# 管理员路径,指向 Django 自带的管理后台
path('admin/', admin.site.urls),
]

# 添加媒体文件访问的 URL 配置
from django.conf import settings
from django.conf.urls.static import static

# 添加媒体文件的 URL 配置,指向 settings 中设置的 MEDIA_ROOT
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

在news文件夹下,我们新建了一个urls.py文件,配置了与主urls.py中类似的路由模式。我们导入了视图函数并设置了两个路径,一个用于新闻列表页,一个用于新闻详情页。我们创建了两个视图函数,一个用于列表页,一个用于详情页,代码如下:

from django.urls import path
from . import views # 从当前应用中导入 views 模块

# 定义 URL 模式列表
urlpatterns = [
# 列表页路径,指向 views 模块中的 news_list 函数
path('list/', views.news_list),
# 详情页路径,使用了动态参数 <int:id> 来匹配新闻的 ID,指向 views 模块中的 detail 函数
path('<int:id>/', views.detail)
]

接着我们需要在news文件夹下views.py中创建两个函数实现了页面的内容,代码如下:

from django.http import HttpResponse
from django.shortcuts import render

def news_list(request):
# 获取新闻列表视图
# 在这个视图函数中,我们渲染一个名为 'list.html' 的模板
return render(request, 'list.html')

def detail(request, id):
# 新闻详情视图
# 在这个视图函数中,我们将渲染一个名为 'detail.html' 的模板来显示特定新闻的详细信息
return render(request, 'detail.html')

在templates文件夹中,我们创建了list.html和detail.html,用于渲染新闻列表页和新闻详情页的内容。如下图所示:

01新建detailhtml.jpg

在list.html列表页中,我们要显示的全部的文章。我们需要在news文件夹下views.py中添加传递全部文章列表的代码并渲染到页面上, 修改代码如下:

from django.http import HttpResponse
from django.shortcuts import render
from news.models import News

def news_list(request):
# 获取所有新闻对象的列表
news_list = News.objects.all()
# 使用 'list.html' 模板渲染页面,并将新闻列表作为上下文传递给模板
return render(request, 'list.html', {'news_list': news_list})

def detail(request, id):
# 新闻详情视图
# 在这个视图函数中,我们将渲染一个名为 'detail.html' 的模板来显示特定新闻的详细信息
return render(request, 'detail.html')

接下来我们在list.html列表页中将需要将文章列表遍历显示每篇文章的标题及文章内容详情页。list.html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% for item in news_list %}
<h2>
<a href="/news/{{ item.id }}">
{ item.title } </a>
</h2>
{% endfor %}
</body>
</html>

在浏览器地址输入:127.0.0.1:8000/news/list/,我们就可以看到每一个标题都添加了一个链接,如下图所示。我们点击不同的标题会进入到不同新闻列表页。

02标题添加链接

在详情页中,我们通过传递文章的id来获取具体的新闻内容,并在模板中展示标题、日期和内容。我们需要在news文件夹下views.py中添加代码并渲染到页面上, 修改代码如下:

from django.http import HttpResponse
from django.shortcuts import render
from news.models import News

def news_list(request):
# 获取所有新闻对象的列表
news_list = News.objects.all()
# 使用 'list.html' 模板渲染页面,并将新闻列表作为上下文传递给模板
return render(request, 'list.html', {'news_list': news_list})

def detail(request, id):
# 根据给定的主键(pk),获取特定的新闻对象
news = News.objects.get(pk=id)
# 使用 'detail.html' 模板渲染页面,并将特定新闻对象作为上下文传递给模板
return render(request, 'detail.html', {'news': news})

在templates文件下的detail.html添加如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>{{f news.title }} </h2>
<p>{{ news.created_at }}</p>
<p>
{{ news.content}}
</p>
</body>
</html>

刷新网站页面,页面中就显示如下内容了:

03页面显示如下内容

为了处理不存在的id,我们添加了异常处理,当id不存在时返回404页面。我们创建了一个404.html模板,并在views.py中进行异常处理,以确保用户能够得到友好的错误提示。新增代码如下:

from django.http import HttpResponse
from django.shortcuts import render
from news.models import News

def news_list(request):
# 获取所有新闻对象的列表
news_list = News.objects.all()
# 使用 'list.html' 模板渲染页面,并将新闻列表作为上下文传递给模板
return render(request, 'list.html', {'news_list': news_list})

def detail(request, id):
try
# 根据给定的主键(pk),获取特定的新闻对象
news = News.objects.get(pk=id)
# 使用 'detail.html' 模板渲染页面,并将特定新闻对象作为上下文传递给模板
return render(request, 'detail.html', {'news': news})
except:
# 如果出现异常(如未找到特定 id 的新闻),返回404页面
return render(request, '404.html')

接着我们在templates文件夹中新建一个404.html文件,html代码如下:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="span4">
<div class="alert alert-danger">
<strong>出错了/(ㄒoㄒ)/~~</strong>&nbsp;&nbsp;
</div>
<img src="{% static 'images/404.png' %}">
</div>
</div>
<div class="row" style="margin-top: 30px">
<a href='#' onClick='history.back(-1);'> <span class="glyphicon glyphicon-menu-left"></span><strong>返回上一页</strong></a>
</div>
</div>
</body>
</html>

404页面中有一张图片需要我们上传到static/images文件夹中,我们上传好,再来刷新页面,这样一个简陋的404页面就做好了,如下图所示:

04404页面

至此,我们已经完成了新闻列表和详情页的功能,但页面还显得比较简陋。下一步,我们将会对页面进行美化,并解决在后台上传的文本无法插入图片和格式化的问题。