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

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中的表关系实现及操作

    表关系的实现   预备知识 ORM的正向操作和反向操作: 1.正向操作:一个模型中定义了一个外键,通过该模型对该外键操作的操作叫做正向操作。 2.反向操作:被外键所关联的模型,通过该模型对外键所在模型的操作叫做反向操作。   表关系的操作 我们通过下面的案例,来了解表关系的操作 首先我们需要几张表:学生表,学生信息表,班级表,报名表,课程表 他们的关系是:学…

    Django 2023年4月16日
    00
  • Django 学习之Celery(芹菜)

    Celery 介绍 文档:http://docs.celeryproject.org/en/latest/index.htmlCelery 是一个功能完备,即插即用的异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务的执行。任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收的工作任务,这个功能依赖于消息队…

    Django 2023年4月11日
    00
  • python-django rest framework框架之视图

    视图 :常用 1和4 两种 1. 原始的APIView class IndexView(views.APIView): def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all() ser = IndexSerializer(instance=user_l…

    Django 2023年4月11日
    00
  • Django与JS交互的示例代码

    接下来我会为你详细介绍如何使用Django与JS进行交互,并提供两个示例说明。 1. Django与JS交互方式汇总 前端与后端之间通信的方式主要有以下几种: 使用模板语言:Django中,可以使用Django自带的模板语言,将变量传递到HTML模板中,JavaScript再从HTML中获取变量。 Ajax:JavaScript通过Ajax发送HTTP请求到…

    Django 2023年5月16日
    00
  • django form关于clean及cleaned_data的说明 以及4种初始化

      1.form类的运行顺序是init,clean,validte,save其中clean和validate会在form.is_valid()方法中被先后调用。(这里留有一个疑问,结构完全相同的两个form,但是一个为先验证后clean,另一个先clean后验证。原因不明。)这里https://docs.djangoproject.com/en/dev/re…

    Django 2023年4月9日
    00
  • python+Django+apache的配置方法详解

    让我们来详细讲解“Python + Django + Apache 的配置方法详解”的完整攻略。本攻略将分为以下五个部分: 安装 Apache、Python 和 Django。 Django 应用程序的设置。 Apache 的设置。 配置整个 Django + Apache 环境。 测试并调试。 下面,我们来逐步进行详细说明。 1. 安装 Apache、Py…

    Django 2023年5月16日
    00
  • Django REST Framework教程:快速入门

    我们将创建一个简单的允许管理员用户查看和编辑系统中的用户和组的API。 项目设置 利用pycharm创建一个名为 tutorial 的新django项目,并创建一个名为 quickstart 的新app。   目录结构        在创建的虚拟环境中安装Django REST framework pip install djangorestframewor…

    Django 2023年4月13日
    00
  • Windows编译安装mod_wsgi,配合使用Django+Apahce

    编译环境: 均是32位版本 Microsoft Visual Studio 10.0 Microsoft SDKs v7.1 Apache2.4 Python3.4 mod_wsgi-4.5.0   要求:   1 Apache和Python都是32位或者都是64位, 2 Apache和Python是相同版本的C++编译器编译的 3 使用和上述相同版本的C+…

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