基于Django搭建简单的博客系统

Django是基于Python的高级Web开发框架。本篇文章进行的是简单的功能的实现,后续会进行安全工具相应的开发。

下面只大致说下过程,具体的实现看源代码即可。


安装:

pip install Django==1.11.4

或直接到Github下载源代码安装

确认是否安装:python –m Django –version


创建新项目:

django-admin startproject djangotest

cd djangotest/

ls


扫描二维码关注公众号,回复: 1434611 查看本文章


项目目录结构如图:


manage.py:与项目进行交互的命令行工具集的入口,即项目管理器,可执行python manage.py来查看所有命令

启动服务:python manage.py runserver 8080

Django shell:python manage.py shell,自动引入项目环境,可以通过其与项目交互进行测试


djangotest目录为一个容器,包含项目的一些基本配置。


wsgi.py:Python Web Server Gateway Interface(Python服务器网关接口),即Python应用与Web服务器之间的接口。


urls.py:URL配置文件


settings.py:

BASE_DIR指定项目根目录。

SECRET_KEY即密钥,项目启动时需要用到。

DEBUG即调试,在测试时用。

ALLOWED_HOSTS即允许访问的主机名,当列表中包含localhost值时即只允许通过localhost的主机名进行访问。

INSTALLED_APPS即已安装的应用,若自己创建了新的应用则添加进去。

MIDDLEWARE即中间件,是Django自带的工具集。

ROOT_URLCONF即URL配置文件,指向urls.py文件。

TEMPLATES即模板,即关于模板的配置,模板简单地说即HTML文件。

WSGI_APPLICATION

DATABASES,数据库配置。

AUTH_PASSWORD_VALIDATORS和密码认证相关。

LANGUAGE_CODE语言编码,默认为en-us。

TIME_ZONE时区,默认为UTC。

USE_I18N

USE_L10N

USE_TZ

STATIC_URL


__init__.py:Python中声明模块的文件,默认内容为空。


创建应用:

新建blog应用:python manage.py startapp blog

接着将新建的应用添加到settings.py的INSTALLED_APPS中:



应用目录:


migrations:数据移植模块,内容自动生成

admin.py:应用的后台管理系统配置

apps.py:当前应用的配置,在Django-1.9后才自动生成

models.py:数据模块,使用ORM框架

tests.py:自动化测试模块,可再次编写测试脚本

views.py:执行响应的代码所在模块,是代码进行逻辑处理的地方,项目中大部分代码在此编写


编写views.py:

每个响应对应一个函数,因而每个函数必须返回一个响应。

函数必须有一个参数,一般约定为request。

每一个响应或函数对应一个URL。



添加内容到urls.py文件:



启动服务:python manage.py runserver 1234

访问相应的目录:



第二种配置url的方法,如注释所说:



直接修改相应的部分:



然后在blog目录下新建urls.py文件:


注意:url函数中的目录名后要添加/,否则容易出错。

再度访问:



Templates模板:

HTML文件,使用Django模板语言(Django Template Language,DTL),也可以使用第三方模板

开发模板的步骤:

1、在根目录下创建Templates目录


2、在该目录下创建HTML文件


3、在views.py中返回render()


访问:


注意点:Django会按照INSTALLED_APPS中的添加顺序来查找Templates。

解决Templates冲突的方法:在Templates目录下创建以APP名为名称的目录并将HTML文件放入新创建的目录中。


另一种创建templates目录是创建在项目的根目录中而不是在应用的目录中,然后再在该目录下创建和应用名一样的目录,再在其中创建html文件即可,注意一点的是,此时因为是创建在项目根目录中,需要在settings.py文件中设置:



Models:

通常一个Model对应数据库的一张表,是以类的形式表现出来的。

示例的models.py文件:



创建步骤:

1、在根目录下创建models.py,并引入models模块

2、创建类,继承models.Model,该类即是一张数据表

3、在类中创建字段

生成数据表:

python manage.py makemigrations app名(可选)

python manage.py migrate



查看:

在根目录的migrations目录中生成移植文件:



可以看到id字段是自动生成的主键,因为在初始创建字段时并没有指定主键。


查看SQL语句:python manage.py sqlmigrate 应用名 文件id



这里使用的是默认的sqlite3数据库,其在根目录中保存为db.sqlite3,查看其需要特定的软件,这里就不下载安装了:



页面呈现数据:

后台修改views.py,添加数据保存到数据库并从数据库读取数据返回到前端:


注意,这里添加id=10的参数是为了每次调用都是进行相同的内容进行替换保存,以避免每调用一次就新增一项数据。


前端修改index.html:

模板直接使用对象以及对象的“.”操作,如{{ article.title }}



最后访问页面即可:



Admin:

Django自带的自动化数据管理界面,被授权的用户可直接在admin中管理数据库。

配置admin:

创建超级用户:python manage.py createsuperuser


访问添加输入admin/目录即可:



可以将页面的英文修改为中文,到settings.py的LANGUAGE_CODE默认的‘en-us’改为‘zh-hans’即可:



配置应用:

在admin.py中引入自身的models模块

编辑admin.py:



刷新页面:



修改数据:


再访问:



修改数据默认名称:


接着在Article类下添加一个方法,根据Python版本,若为3以上版本则使用__str__(self)方法,若为2系列版本则使用__unicode__(self)方法,添加这个方法是为了在查询时实现相应的内容,这里是实现将显示的内容从对象改为文章标题:


再次查看:



改进:

在admin.py中添加ArticleAdmin类并通过list_display来设置文章列表显示页面中显示的列的内容:




完善Blog开发:

namespace与name参数的注意点:

1、写在include()的第二个参数位置,namespace=’blog’

先在djangotest/djangotest/urls.py的include()函数中添加namespace参数:



2、应用下则写在url()的第三个参数位置,name=’article_page’

然后到djangotest/blog/urls.py中的url()函数中添加name参数:


主要取决于是否使用include引用另一个url配置文件。


最后在HTML文件中:

template中超链接href可以用“{% url ‘app_name:url_name’ param %}”

app_name和url_name都在urls.py中配置



Blog编写页面:添加了编辑、删除、返回主页、登出等链接,具体看代码。


认证登录:

contrib模块:django.contrib.auth,默认的认证框架。

创建users:

1、示例代码如下:

from django.contrib.auth.models import User
user = User.objects.create_user(‘admin’, ‘[email protected]’, ‘password’)

2、python manage.py createsuperuser


修改密码:

1、python manage.py changepassword username

2、示例代码如下:

from django.contrib.auth.models import User
u = User.objects.get(username=’admin’)
u.set_password(‘newpassword’)
u.save()


认证Users:authenticate(username=’admin’, password=’password’),成功则返回User对象,否则返回None。

Web请求中的认证:request.user.is_authenticated()

登录用户:login(request, user),需要先进行认证

登出用户:logout(request)

只允许用户登录访问:

1、检查request.user.is_authenticated()

2、login_required装饰器


先创建一个member应用,在settings.py中添加应用名,然后创建forms.py:


主要是创建用户名和密码的表单类,其中Django用widget来定义数据项的格式,这里为密码格式的文本字段。

然后创建urls.py文件:


在views.py中编写用户登录的方法user_login()。

接着对之前blog应用的views.py中的方法调用login_required()方法进行装饰:


然后再在urls.py中配置一下url即可完成登录相关的功能。


代码实现:

这里重新新建项目来实现博客系统完整的搭建。

整个项目目录架构如下:



blog目录:

admin.py:

from django.contrib import admin

from models import Article

# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
	"""docstring for ArticleAdmin"""
	list_display = ('title', 'content', 'pub_time')
	list_filter = ('pub_time',)
		
admin.site.register(Article, ArticleAdmin)


models.py:

from __future__ import unicode_literals

from django.db import models

# Create your models here.
class Article(models.Model):
	title = models.CharField(max_length=32, default='title')
	content = models.TextField(null=True)
	pub_time = models.DateTimeField(null=True)

	def __unicode__(self):
		return self.title


urls.py:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^index/$', views.index, name='index'),
    url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
    url(r'^edit/(?P<article_id>[0-9]+)$', views.edit_page, name='edit_page'),
    url(r'^change/$', views.change, name='change'),
    url(r'^delete/(?P<article_id>[0-9]+)$', views.delete_page, name='delete_page'),
]


views.py:

from django.shortcuts import render
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required

from . import models

# Create your views here.
@login_required
def index(request):
	articles = models.Article.objects.all()
	return render(request, 'blog/index.html', {'articles':articles})

@login_required
def article_page(request, article_id):
	article = models.Article.objects.get(pk=article_id)
	return render(request, 'blog/article_page.html', {'article':article})

@login_required
def edit_page(request, article_id):
	if str(article_id) == '0':
		return render(request, 'blog/edit_page.html')
	article = models.Article.objects.get(pk=article_id)
	return render(request, 'blog/edit_page.html', {'article':article})

@login_required
def change(request):
	title = request.POST.get('title', 'TITLE')
	content = request.POST.get('content', 'CONTENT')
	article_id = request.POST.get('article_id', '0')
	if article_id == '0':
		models.Article.objects.create(title=title, content=content)
		articles = models.Article.objects.all()
		return render(request, 'blog/index.html', {'articles':articles})

	article = models.Article.objects.get(pk=article_id)
	article.title = title
	article.content = content
	article.save()
	return render(request, 'blog/article_page.html',  {'article':article})

@login_required
def delete_page(request, article_id):
	models.Article.objects.filter(pk=article_id).delete()
	articles = models.Article.objects.all()
	return render(request, 'blog/index.html', {'articles':articles})


member目录:

forms.py:

from django import forms

class LoginForm(forms.Form):
	username = forms.CharField()
	password = forms.CharField(widget=forms.PasswordInput)
		


urls.py:

from django.conf.urls import url
from django.contrib.auth import views as auth_views

from . import views

urlpatterns = [
	url(r'^$', views.user_login, name='login'),
	url(r'^logout-then-login/$', auth_views.logout_then_login, name='logout_then_login'),
]


views.py:

from __future__ import unicode_literals

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib.auth import authenticate, login
from django.contrib import messages

from .forms import LoginForm

# Create your views here.
def user_login(request):
	login_form = LoginForm()
	if request.method == 'POST':
		form = LoginForm(request.POST)
		if form.is_valid():
			cd = form.cleaned_data
			user = authenticate(username=cd['username'], password=cd['password'])
			if user is not None:
				if user.is_active:
					login(request, user)
					return HttpResponseRedirect('/blog/index')
				else:
					messages.error(request, "Your username and password didn't match.")
					return HttpResponseRedirect('/')
			else:
				messages.error(request, "Your username and password didn't match.")
				return HttpResponseRedirect('/')
	else:
		return render(request, 'login/user_login.html', {'login_form':login_form})


myBlog目录:

urls.py:

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^blog/', include('blog.urls', namespace='blog')),
    url(r'^', include('member.urls', namespace='member')),
    url(r'^accounts/login/', include('member.urls')),
]


settings.py中修改几个地方即可:





templates目录:

login目录:

user_login.html:

<!DOCTYPE html>
<head>
<meta charset="utf-8"/>
<title>MyBlog</title>
</head>
<body class="login">
<h2>MyBlog——简单的博客系统</h2>
<div>
	<form action="{% url 'member:login' %}" method="post">
		<h3>Login to your account</h3>
		{% if messages %}
		<h5>
			{% for message in messages %}
				{{ message }}
			{% endfor %}
		</h5>
		{% endif %}
		<div>
			<label>Username</label>
			<div>
				<input type="text" autocomplete="off" placeholder="Username" name="username"/>
			</div>
		</div>
		<br/>
		<div >
			<label>Password</label>
			<div>
				<input type="password" autocomplete="off" placeholder="Password" name="password"/>
			</div>
		</div>
		<br/>
		{% csrf_token %}
		<div>
			<button type="submit">
			Login
			</button>
		</div>
	</form>
</div>
<br>
<div class="copyright">
	 2017 &copy; SKI12
</div>
</body>
</html>


blog目录:

index.html:

<!DOCTYPE html>
<html>
<head>
	<title>MyBlog</title>
</head>
<body>
<h1>MyBlog</h1>
<a href="{% url 'blog:edit_page' 0 %}">编写博客</a>
<p>博客列表</p>
{% for article in articles %}
	<a href="{% url 'blog:article_page' article.id %}">{{ article.title }}</a>
	<br/>
{% endfor %}
<br>
<a href="{% url 'member:logout_then_login' %}">Logout</a>
</body>
</html>


article_page.html:

<!DOCTYPE html>
<html>
<head>
	<title>Article Page</title>
</head>
<body>
<h1>{{ article.title }}</h1>
<br/>
<h3>{{ article.content }}</h3>
<br/>
<br/>
<a href="{% url 'blog:edit_page' article.id %}">Edit</a>
<a href="{% url 'blog:delete_page' article.id %}">Delete</a>
<a href="{% url 'blog:index'%}">Home</a>
<a href="{% url 'member:logout_then_login' %}">Logout</a>
</body>
</html>


edit_page.html:

<!DOCTYPE html>
<html>
<head>
	<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:change' %}" method="post">
	{% csrf_token %}
	<input type="hidden" name="article_id" value="{{ article.id | default:'0' }}">
	<label>文章标题
		<input type="text" name="title" value="{{ article.title }}" />
	</label>
	<br/>
	<label>文章内容
		<input type="text" name="content" value="{{ article.content }}">
	</label>
	<br/>
	<input type="submit" value="提交">
</form>
<br/>
<div>
	<a href="{% url 'blog:index'%}">Home</a>
	<a href="{% url 'member:logout_then_login' %}">Logout</a>
</div>
</body>
</html>


最终的超简版博客系统效果如图:

首先访问的时候需要登录:


登录成功后转到blog主页:


点击编写博客进入编辑页面:


点击博客文章查看博客:


简易的功能完成了,后面就进一步进行安全开发。

猜你喜欢

转载自blog.csdn.net/ski_12/article/details/78505235