本期内容:基于Django与HTML的简单新闻发布系统。
项目需求:Python+Django
项目下载地址:https://download.csdn.net/download/m0_68111267/88728636
本期博主将带着大家用Django完成一个简单的新闻发布系统,该新闻发布系统具有“登录界面”,“注册界面”,“新闻界面”以及“后台界面”。
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django
django-admin startproject newsProject
cd newsProject
django-admin startapp news
from django.contrib import admin
from django.urls import path
from news import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home),
path('regist/', views.regist),
path('login/', views.login),
path('logout/', views.logout),
path('article/', views.article),
path('<int:id>/', views.detail, name='detail'),
]
注意代码里的views可能会爆红,这是因为我们还没有配置"views"视图文件,下面就让我们一起来配置一下吧~
双击打开"news"目录下的"views.py"文件,配置项目的视图函数
from django.shortcuts import render, redirect
from django.http import HttpResponse, Http404
from .models import Article
from django.contrib import auth
from django import forms
from django.contrib.auth.models import User
class UserForm(forms.Form):
username = forms.CharField(label='用户名', max_length=100)
password = forms.CharField(label='密 码', widget=forms.PasswordInput())
# 主界面
def home(request):
return render(request, 'home.html')
# 用户注册界面
def regist(request):
if request.method == 'POST':
uf = UserForm(request.POST) # 包含用户名和密码
if uf.is_valid():
# 获取表单数据
username = uf.cleaned_data['username'] # cleaned_data类型是字典,里面是提交成功后的信息
password = uf.cleaned_data['password']
# 添加到数据库
registAdd = None
try:
registAdd = User.objects.create_user(username=username, password=password)
return render(request, 'regists.html', {'registAdd': registAdd})
except:
return render(request, 'regists.html', {'registAdd': registAdd, 'username': username})
else:
# 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空
uf = UserForm()
return render(request, 'regist.html', {'uf': uf})
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
match = auth.authenticate(username=username, password=password) # 用户认证
if match is not None: # 如果数据库里有记录(即与数据库里的数据相匹配或者对应或者符合)
auth.login(request, match) # 登陆成功
return redirect('/', {'user': match}) # 跳转--redirect指从一个旧的url转到一个新的url
else: # 数据库里不存在与之对应的数据
return render(request, 'login.html', {'login_error': '用户名或密码错误'}) # 登录失败
return render(request, 'login.html')
def logout(request):
auth.logout(request)
return render(request, 'home.html')
def article(request):
article_list = Article.objects.all()
# QuerySet是一个可遍历结构,包含一个或多个元素,每个元素都是一个Model实例
# QuerySet类似于Python中的list,list的一些方法QuerySet也有,比如切片,遍历。
# 每个Model都有一个默认的manager实例,名为objects,QuerySet有两种来源:通过manager的方法得到、通过QuerySet的方法得到。mananger的方法和QuerySet的方法大部分同名,同意思,如filter(),update()等,但也有些不同,如manager有create()、get_or_create(),而QuerySet有delete()等
return render(request, 'article.html', {'article_list': article_list})
def detail(request, id):
try:
article = Article.objects.get(id=id)
# print type(article)
except Article.DoesNotExist:
raise Http404
return render(request, 'detail.html', locals())
该段代码是一个基于Django框架的用户注册和登录功能实现。主要包含以下几个函数:
home(request)
: 主界面,渲染home.html模板。
regist(request)
: 用户注册界面。如果请求为POST方法,从表单中获取用户名和密码,将其添加到数据库中创建新用户。如果注册成功,渲染regists.html模板并传递注册成功的信息。如果注册失败,渲染regists.html模板并传递错误信息。如果请求为GET方法,直接渲染regist.html模板。
login(request)
: 用户登录界面。如果请求为POST方法,从表单中获取用户名和密码,使用auth.authenticate()
函数进行用户认证。如果认证成功,调用auth.login()
函数进行登录并重定向到主页。如果认证失败,渲染login.html模板并传递错误信息。
logout(request)
: 用户注销功能。调用auth.logout()
函数进行注销,并渲染home.html模板。
article(request)
: 文章列表页面。从数据库中获取所有文章对象,并渲染article.html模板并传递文章列表。
detail(request, id)
: 文章详情页面。根据文章的id从数据库中获取对应的文章对象,并渲染detail.html模板并传递文章对象。
注意:此时的"Article"会爆红,因为我们还没有配置"models.py"模型文件哦
接下来我们就来配置"news"的"models.py"模型文件吧
from django.db import models
class Article(models.Model):
title = models.CharField('标题', max_length=256)
content = models.TextField('内容')
pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
update_time = models.DateTimeField('更新时间', auto_now=True, null=True)
def __str__(self):
return self.title
该代码段定义了一个名为Article的模型类,用于表示文章对象。
该模型类继承自Django提供的models.Model
基类,以便使用Django的数据库功能。
模型类包含以下几个字段:
title
: 标题字段,使用CharField
类型,最大长度为256字符。
content
: 内容字段,使用TextField
类型,可以存储较长的文本内容。
pub_date
: 发表时间字段,使用DateTimeField
类型,自动记录发表时间,并设置为只读(不可编辑)。
update_time
: 更新时间字段,使用DateTimeField
类型,自动记录最后更新时间,并在更新时进行更新,允许为空。
模型类还定义了一个__str__()
方法,用于在对象被打印或字符串表示时返回标题字段的值。
该模型类的目的是在数据库中创建一个名为Article的表,用于存储文章的相关信息,如标题、内容、发表时间和更新时间等。
通过使用该模型类,可以方便地对文章对象进行创建、查询、更新和删除操作。
最后我们需要配置一下"news"里的"admin.py"文件
from django.contrib import admin
from news.models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title','pub_date', 'update_time',)
admin.site.register(Article, ArticleAdmin)
这段代码是在Django的admin.py文件中注册一个模型(Model)并配置相应的管理选项。
首先,我们导入了admin模块,并导入了Article模型(假设该模型定义在news.models文件中)。
然后,我们定义了一个名为ArticleAdmin的类,继承自admin.ModelAdmin。该类用于配置Article模型在Django admin后台的显示和操作选项。
在这个类中,我们设置了list_display属性,它是一个包含模型字段名称的元组。这个属性指定了在Django admin后台中列表视图显示的字段。在这个例子中,我们指定了’title’(标题)、‘pub_date’(发布日期)和’update_time’(更新时间)。
最后,我们调用admin.site.register()方法,将Article模型和ArticleAdmin类进行注册。这告诉Django admin后台要管理Article模型,并使用ArticleAdmin类中指定的配置选项。
通过这段代码,您就可以在Django admin后台中管理Article模型,并可以根据设置的list_display属性在列表视图中显示指定的字段。
本项目共需要创建六个模板文件,首先我们需要在"news"目录下新建一个"templates"子目录,然后在"templates"目录中创建六个文件(页面):
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A layout example that shows off a blog page with a list of posts.">
<title>新闻系统</title>
<link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/pure-min.css">
<link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/grids-responsive-min.css">
<link rel="stylesheet" href="http://labfile.oss.aliyuncs.com/courses/487/blog.css">
</head>
<body>
<div id="layout" class="pure-g">
<div class="sidebar pure-u-1 pure-u-md-1-4">
<div class="header">
<h1 class="brand-title"><a href="#"> Want595最新要闻</a>
……具体代码需要下载后查看哦~
该HTML模板文件用于渲染新闻系统的页面布局。
页面布局分为两个部分:侧边栏(sidebar)和内容区域(content)。
侧边栏部分包含以下内容:
网站标题和标语,用<h1>
和<h2>
标签进行展示。
导航栏,包含一个无序列表(<ul>
),其中的列表项(<li>
)包含以下内容:
内容区域部分使用一个<div>
元素包裹,用于渲染具体的页面内容。在模板中使用了一个{% block content %}
标签,表示该区域是一个可被子模板继承并填充内容的区域。
该模板文件使用了PureCSS框架提供的样式表,以实现页面的样式和布局。
通过使用该模板文件,可以方便地创建新闻系统的页面布局,并根据具体需求填充和扩展页面内容。
{% extends 'home.html' %}
{% block content %}
<h1>注册页面</h1>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{uf.as_p}}
<input type="submit" value="OK" />
</form>
{% endblock %}
这个模板继承自一个名为home.html
的父模板,通过{% extends 'home.html' %}
指令进行继承。
在模板中使用了一个{% block content %}
标签来填充内容,表示该区域是可以被父模板中同名块所替换的区域。
具体内容如下:
使用<h1>
标签显示了一个标题为"注册页面"的标题。
使用<form>
标签创建了一个表单,其中method
属性指定了使用POST方法提交表单数据,enctype
属性指定了表单数据的编码方式为multipart/form-data
。
使用{% csrf_token %}
标签生成一个CSRF令牌,用于防止跨站请求伪造。
使用{{ uf.as_p }}
渲染了一个表单对象uf
,其中的as_p
方法会将表单字段渲染为<p>
标签的形式,方便显示字段和输入框。
使用<input>
标签创建了一个类型为"submit"的按钮,显示文本为"OK",用于提交表单。
通过这个模板,可以在注册页面中显示一个表单,接收用户的注册信息,并通过提交按钮将信息发送给服务器进行处理。
{% extends 'home.html' %}
{% block content %}
{{registAdd}}
<br>
================
<br>
{% if username %}
注册失败,{{ username }}已存在!
<a href="/regist">注册</a>
{% else %}
注册成功!
<a href="/login">登录</a>
{% endif %}
{% endblock %}
这个模板继承自一个名为home.html
的父模板,通过{% extends 'home.html' %}
指令进行继承。
在模板中使用了一个{% block content %}
标签来填充内容,表示该区域是可以被父模板中同名块所替换的区域。
具体内容如下:
使用{{registAdd}}
语句输出了一个变量registAdd
的值。根据上下文来看,这个变量可能是在视图函数中传递给模板的。
使用<br>
标签插入一个换行。
使用{% if username %}
条件语句,判断变量username
是否存在。
如果username
存在,输出"注册失败"和username
已存在的提示信息,同时提供一个"注册"的链接用于重新注册。
如果username
不存在,输出"注册成功!"的提示信息,同时提供一个"登录"的链接用于跳转到登录页面。
通过这个模板,可以根据不同的情况在注册结果页面显示不同的提示信息,给用户提供相应的操作选项。
{% extends 'home.html' %}
{% block content %}
<div>
<form action="/login/" method="POST">{% csrf_token %}
<h2>请登录</h2>
<input type="text" name="username" />
<input type="password" name="password" />
<button type="submit">登录</button>
<p style="color: red">{{ login_error }}</p>
</form>
</div>
{% endblock %}
这个模板继承自一个名为home.html
的父模板,通过{% extends 'home.html' %}
指令进行继承。
在模板中使用了一个{% block content %}
标签来填充内容,表示该区域是可以被父模板中同名块所替换的区域。
具体内容如下:
使用<div>
元素包裹了一个表单,该表单的提交目标为"/login/",使用POST方法提交数据。
使用{% csrf_token %}
模板标签添加一个跨站请求伪造保护的令牌。
使用<h2>
标签显示"请登录"的标题。
使用两个<input>
标签分别用于输入用户名和密码,分别对应name="username"
和name="password"
。
使用<button>
标签显示一个"登录"按钮。
使用<p>
标签显示一个红色文本,该文本内容由login_error
变量提供,用于显示登录出现的错误信息。
通过这个模板,用户可以在登录页面输入用户名和密码,并点击登录按钮进行登录操作。如果登录失败,会显示相应的错误信息。
{% extends 'home.html' %}
{% block content %}
<h2>新闻列表</h2>
{% for article in article_list %}
<h3><a href="{% url 'detail' id=article.id %}">{{ article.title }}</a></h3>
{% endfor %}
{% endblock %}
这个模板继承自一个名为home.html
的父模板,通过{% extends 'home.html' %}
指令进行继承。
在模板中使用了一个{% block content %}
标签来填充内容,表示该区域是可以被父模板中同名块所替换的区域。
具体内容如下:
使用<h2>
标签显示"新闻列表"的标题。
使用{% for article in article_list %}
模板标签开始一个循环,遍历article_list
列表中的每个元素。
在循环内部,使用<h3>
标签显示每篇文章的标题,并且使用{% url 'detail' id=article.id %}
生成文章详情页面的链接。
使用{% endfor %}
结束循环。
通过这个模板,可以在页面上显示新闻列表,并且每个新闻标题都有对应的链接可以跳转到相应的新闻详情页面。
{% extends 'home.html' %}
{% block content %}
<h2>{{ article.title }}</h2>
{{ article.content }}
{% endblock %}
这个模板继承自一个名为home.html
的父模板,通过{% extends 'home.html' %}
指令进行继承。
在模板中使用了一个{% block content %}
标签来填充内容,表示该区域是可以被父模板中同名块所替换的区域。
具体内容如下:
使用<h2>
标签显示article
对象的标题,通过{{ article.title }}
获取到文章标题的值。
使用{{ article.content }}
显示article
对象的内容,通过{{ article.content }}
获取到文章内容的值。
通过这个模板,可以在页面上显示文章的标题和内容。
在终端输入以下命令创建(迁移)数据库
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
我是一只有趣的兔子,感谢你的喜欢!