Python Django实现个人博客系统的搭建攻略
简介
Python的Django框架在web开发中应用广泛,本文将介绍如何使用Django框架搭建个人博客系统。该博客系统除常见博客功能外,还包含用户身份验证,文章归档,评论系统等功能。
必要的工具及技能
在开始搭建博客系统前,需要准备好以下工具及技能:
- Python3.x
- Django
- HTML,CSS,JavaScript等前端技能
配置Django环境
- 安装Python3.x,这里以Python3.9为例(Windows平台):
bash
$ python3.9.exe -m venv myvenv #创建虚拟环境 myvenv
$ cd myvenv/Scripts/ #进入虚拟环境
$ activate # 激活虚拟环境 - 通过pip安装Django
bash
(myvenv) $ pip install django
创建Django项目
- 通过Django CLI创建新项目
bash
(myvenv) $ django-admin startproject myproject
创建博客应用
- 通过Django CLI创建新应用
bash
(myvenv) $ cd myproject
(myvenv) $ python manage.py startapp blog - 创建Django模型,设置数据库
```python
# 在blog/models.py中定义文章和评论模型
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey('auth.user', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
create_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey('blog.Post', related_name='comments', on_delete=models.CASCADE)
author = models.CharField(max_length=200)
text = models.TextField()
create_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text
在已安装的数据库中创建数据表
bash
(myvenv) $ python manage.py makemigrations blog
(myvenv) $ python manage.py migrate blog
```
创建视图,处理用户请求
- 定义视图函数,使用模板返回HTML页面
```python
# 在blog/views.py文件中定义处理请求的视图函数
from django.shortcuts import render, get_object_or_404, redirect
from django.utils import timezone
from blog.forms import PostForm, CommentForm
from blog.models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
comments = post.comments.filter(approved_comment=True)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('blog.views.post_detail', pk=post.pk)
else:
form = CommentForm()
return render(request, 'blog/post_detail.html', {'post': post, 'comments': comments, 'form': form})
def post_new(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('blog.views.post_detail', pk=post.pk)
else:
form = PostForm()
return render(request, 'blog/post_edit.html', {'form': form})
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('blog.views.post_detail', pk=post.pk)
else:
form = PostForm(instance=post)
return render(request, 'blog/post_edit.html', {'form': form, 'post': post})
在blog应用内创建`form.py`文件,定义文章和评论表单
python
from django import forms
from blog.models import Post, Comment
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('author', 'text',)
在`myproject/myproject/settings.py`文件中添加`blog`应用,设置静态文件,模板路径等
python
INSTALLED_APPS = [
'blog',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
```
创建模板,渲染HTML页面
- 创建博客系统的HTML页面
- 在
myproject/templates/blog
目录下添加post_list.html
,post_detail.html
和post_edit.html
文件 - 可以使用Bootstrap等前端框架渲染博客页面
- 代码示例
```html
{% extends 'blog/base.html' %}
{% block content %}
{% endfor %}
{% endblock content %}
{% extends 'blog/base.html' %}
{% block content %}
{{ post.published_date }}
{{ post.title }}
{{ post.text|linebreaksbr }}
{% empty %}
No comments here yet :(
{% endfor %}
{% endblock content %}
{% extends 'blog/base.html' %}
{% block content %}
{% endblock content %}
- 创建base.html作为页面的基本框架,作为其他模板继承
html
{% endblock content %}
```
运行和测试博客系统
- 启动Django服务器
bash
(myvenv) $ python manage.py runserver - 在浏览器中访问
http://127.0.0.1:8000/
查看博客系统
示例说明
示例1:添加用户身份验证
为了添加用户身份验证,我们需要在模型中定义用户,添加用户注册和登录的视图函数。
用户模型
# 基于Django内置的auth User模型扩展UserProfile模型
from django.contrib.auth.models import User
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
avatar = models.ImageField(upload_to='avatar', blank=True)
def __str__(self):
return self.user.username
用户注册视图函数
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db()
user.profile.avatar = request.FILES['avatar']
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('blog.views.post_list')
else:
form = UserCreationForm()
return render(request, 'registration/signup.html', {'form': form})
用户登录视图函数
from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('blog_v2:post_list')
else:
form = AuthenticationForm()
return render(request, 'registration/login.html', {'form': form})
示例2:添加文章归档
在博客系统中添加文章归档需要在视图函数内根据发布时间进行聚类。
归档视图函数
from django.shortcuts import render
from django.db.models import Count
from blog.models import Post
def post_archive(request):
return render(request, 'blog/post_archive.html')
def post_archive_year(request, year):
posts = Post.objects.filter(published_date__year=year)
post_count = posts.count()
context = {
'year': year,
'posts': posts,
'post_count': post_count,
}
return render(request, 'blog/post_archive_year.html', context)
def post_archive_month(request, year, month):
posts = Post.objects.filter(published_date__year=year, published_date__month=month)
post_count = posts.count()
context = {
'year': year,
'month': month,
'posts': posts,
'post_count': post_count,
}
return render(request, 'blog/post_archive_month.html', context)
def post_archive_day(request, year, month, day):
posts = Post.objects.filter(published_date__year=year, published_date__month=month, published_date__day=day)
post_count = posts.count()
context = {
'year': year,
'month': month,
'day': day,
'posts': posts,
'post_count': post_count,
}
return render(request, 'blog/post_archive_day.html', context)
def post_archive_list(request):
archive = Post.objects.annotate(year=ExtractYear('published_date'), month=ExtractMonth('published_date')).values('year', 'month').annotate(count=Count('id'))
context = {'archive': archive}
return render(request, 'blog/post_archive_list.html', context)
归档HTML模板
<!-- post_archive_list.html -->
{% extends 'blog/base.html' %}
{% block content %}
<div class="content-section">
<div class="container">
<div class="row">
<div class="col-lg-8">
<h1 class="mt-0">Archive</h1>
<ul>
{% for year in archive %}
<li><a href="{% url 'blog.views.post_archive_year' year=year.year %}">{{ year.year }} ({{ year.count }})</a>
<ul>
{% for month in year.month|slice:":" %}
<li><a href="{% url 'blog.views.post_archive_month' year=year.year month=month|date:"m" %}">{{ month|date:"F" }} ({{ month.posts.count }})</a>
<ul>
{% for post in month.posts %}
<li><a href="{% url 'blog.views.post_detail' pk=post.pk %}">{{ post.title }}</a></li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endblock content %}
归档URL定义
from django.urls import path
from blog.views import post_archive_list, post_archive_year, post_archive_month, post_archive_day
urlpatterns = [
path('archive/', post_archive_list, name='post_archive_list'),
path('archive/<int:year>/', post_archive_year, name='post_archive_year'),
path('archive/<int:year>/<int:month>/', post_archive_month, name='post_archive_month'),
path('archive/<int:year>/<int:month>/<int:day>/', post_archive_day, name='post_archive_day'),
]
结语
通过本文的介绍,您可以完成一个基本的个人博客系统搭建。在博客系统中包含用户身份验证和文章
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python Django实现个人博客系统的搭建 - Python技术站
Remove
{{ comment.author }}
{{ comment.text|linebreaksbr }}