Python Django实现个人博客系统的搭建

yizhihongxing

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.htmlpost_detail.htmlpost_edit.html文件
  • 可以使用Bootstrap等前端框架渲染博客页面
  • 代码示例
    ```html

{% extends 'blog/base.html' %}

{% block content %}

{% for post in posts %}

{{ post.published_date }}

{{ post.title }}

{{ post.text|linebreaksbr }}

{% endfor %}

{% endblock content %}

{% extends 'blog/base.html' %}

{% block content %}

{{ post.published_date }}

{{ post.title }}

{{ post.text|linebreaksbr }}


{% for comment in comments %}

{{ comment.create_date }}
Remove

{{ comment.author }}

{{ comment.text|linebreaksbr }}

{% empty %}

No comments here yet :(

{% endfor %}


{% csrf_token %}
{{ form.as_p }}

{% endblock content %}

{% extends 'blog/base.html' %}

{% block content %}

{% csrf_token %}
{{ form.as_p }}

{% endblock content %}
- 创建base.html作为页面的基本框架,作为其他模板继承html





{% block title %}{% endblock title %}

{% block content %}
{% 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技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • django认证系统 Authentication使用详解

    下面我将为您详细讲解“Django认证系统Authentication使用详解”的完整攻略,包含两条示例说明。 一、什么是Django认证系统? Django认证系统是一个内置于Django框架中的用户管理系统。它提供了用户认证、密码重置、用户注册等一系列功能,方便开发者快速实现认证与授权功能。 二、如何使用Django认证系统? 1. 配置认证系统 在se…

    Django 2023年5月16日
    00
  • Django 中的装饰器的使用

    1、CBV实现的登录视图 class LoginView(View): def get(self, request): “”” 处理GET请求 “”” return render(request, ‘login.html’) def post(self, request): “”” 处理POST请求 “”” user = request.POST.get(‘…

    Django 2023年4月12日
    00
  • Anaconda+django写出第一个web app(四)

    前面对Models有了一些了解,今天开始进一步了解Views,了解Views如何和Models交互以及了解模板(templates)。 打开main文件夹下的views.py,重新编写homepage函数,render的用法可在帮助文档 [1]中查看: from django.shortcuts import render from django.http …

    Django 2023年4月11日
    00
  • django os.environ慎用setdefault操作环境变量

    在绝大多数情况下,如果需要在程序运行过程中设置环境变量,使用os.environ.setdefault函数是没有任何问题的,但是有两种场景下setdefault会造成意外的问题,需要慎用: 如果程序执行前,系统里已经存在了某环境变量(如ENV=VAL1),此时如果在程序中用setdefault函数对该环境变量设置另一个不同的值(如VAL2),会因为setde…

    Django 2023年4月13日
    00
  • Django中图片显示不出来

    参考: http://my.oschina.net/wenhaowu/blog/197035 http://blog.csdn.net/thy38/article/details/23553975 http://www.tuicool.com/articles/i6NVNrq http://www.cnblogs.com/wang_yb/archive/20…

    Django 2023年4月12日
    00
  • Django常见错误信息汇总及解决方案

    摘要:最近学习Django中,自己随便写写还是碰到了挺多问题,不过貌似都是比较常见,还能顺利解决。现在写下来,也许以后会忘记,也许能帮上碰到同样问题的 小编我前面已经写过一篇关于Django常见错误的文章了,该文比较适合新手阅读,防止学习Django过程中入坑。今天小编我要总结实际Django开发过程中和debug过程中经常碰到的错误信息以及如何解决它们。本…

    Django 2023年4月15日
    00
  • Django的安装、使用详解、自动化测试应用以及程序打包

    1、Django的安装 pip install Django 验证 Django 是否能被 Python 识别 >>> import django >>> print(django.get_version()) 2.2.6 2、创建Django项目脚手架(里面mysite 是Django容器) cd 到一个你想放置你代码的…

    Django 2023年4月13日
    00
  • django 静态资源配置

    最近在学习一个项目,django框架,但当 render 模板时,模板里有引入的图片就访问不到, 这是因为 django部署方式比较特别,采用静态文件路径:STATICFILES_DIRS的部署方式,之前你写的相对路径,绝对路径因为缺少静态文件路径而全部失效 解决办法: 步骤1:在settings.py文件的最后加上以下内容: STATIC_URL = ‘/…

    Django 2023年4月11日
    00
合作推广
合作推广
分享本页
返回顶部