博客系统项目:编码篇-基础篇-架构搭建

博客系统项目:编码篇-基础篇-架构搭建,第1张

博客系统项目:编码篇-基础篇-架构搭建

博客系统项目:编码篇-基础篇
  • 1 背景
  • 2 环境
    • 2.1 环境说明
    • 2.2 模式说明
        • 2.2.1 MTV模式
        • 2.2.2 MVC
  • 3 前置工作
    • 3.1 环境搭建
  • 4 编码实现
    • 4.1 项目调整
      • 4.1.1 修改语言时区
      • 4.1.2 添加应用路由
      • 4.1.3 添加项目路由
      • 4.1.4 添加应用视图
      • 4.1.5 生成迁移文件
      • 4.1.6 项目中添加应用
    • 4.2 模型
      • 4.2.1 编辑项目模型
      • 4.2.2 生成模型文件
    • 4.3 视图
      • 4.3.1 前端视图
      • 4.3.2 后台页面
  • 参考链接

1 背景

在上一篇中介绍了《博客系统项目:设计篇》从整体上介绍了博客系统的设计方法和思路,本篇围绕设计出具博客系统的具体编码,设计出具后紧接着就到编码阶段,编码阶段涉及到开发环境的选择、开发语言的选型、开发框架的选型、数据库选型、IDE的选型、以及软件架构模式选型。在本篇中会集中介绍,在系统中有一个最小系统法的原则,包括我们组装计算机和器械过程中都会用到这个原则,即用最少和必要的部件以最少的时间最快的速度组装出一台计算机,加电启动,确认启动正常输出硬件信息,既可以进行后面的完整安装。

2 环境 2.1 环境说明 项目工具开发环境Ubuntu 18.04 TLS开发语言Python3.6.9虚拟环境virtualenv15.1.0开发框架Django3.2.9数据库sqlite3IDE集成开发环境vscode1.63.2设计模式模型-模板-视图 MTV 2.2 模式说明 2.2.1 MTV模式

介绍一下设计模式,MTV模式是Django 的设计模式。其借鉴了MVC模式,将交互过程分为3个层次:

  • Model:数据存储层,处理所有数据相关的业务,和数据库进行交互,并提供数据的增删改查;
  • Template:模板层(也叫表现层)具体来处理页面的显示;
  • View:业务逻辑层,处理具体的业务逻辑,它的作用是连通Model 层和
    Template 。

  1. 用户通过浏览器对服务器发起 request 请求,服务器接收请求后,通过 View 的业务逻辑层进行分析,同时向 Model 层和Template 层发送指令;

  2. Mole 层与数据库进行交互,将数据返回给 View 层;

  3. Template层接收到指令后,调用相应的模板,并返回给 View 层;

  4. 层接收到模板与数据后,首先对模板进行渲染(即将相应的数据赋值给模板),然后组织成响应格式返回给浏览器,浏览器进行解析后并最终呈现给用户。

2.2.2 MVC

在开发领域,MVC模式是非常出门的一种设计模式,
MVC 是 Model-View-Controller 的缩写,其中每个单词都有其不同的含义:

  • Modle 代表数据存储层,是对数据表的定义和数据的增删改查;
  • View 代表视图层,是系统前端显示部分,它负责显示什么和如何进行显示;
  • Controller 代表控制层,负责根据从 View 层输入的指令来检索 Model 层的数据,并在该层编写代码产生结果并输出。 PHP语言框架中 laravel 使用的是MVC模式


请求与响应过程描述如下:

  1. 用户通过浏览器向服务器发起 request 请求,Controller 层接受请求后,同时向 Model 层和 View 发送指令;
  2. Mole 层根据指令与数据库交互并选择相应业务数据,然后将数据发送给 Controller 层;
  3. View 层接收到Controller 的指令后,加载用户请求的页面,并将此页面发送给 Controller 层;
  4. Controller 层接收到 Model 层和 View 层的数据后,将它们组织成响应格式发送给浏览器,浏览器通过解析后把页面展示出来。

MVC 的 3 层之间紧密相连,但又相互独立,每一层的修改都不会影响其它层,每一层都提供了各自独立的接口供其它层调用,MVC 的设计模式降低了代码之间的耦合性(即关联性),增加了模块的可重用性,这就是 MVC 的设计模式。
Laravel框架采用了MVC模式,Django采用MTV模式。

3 前置工作

编码阶段包括虚拟环境的创建、框架的安装、项目创建、应用创建、模型编写、模板引用、视图编写、运行测试。

3.1 环境搭建

查看python版本

python3 --version

Python 3.6.9
安装虚拟环境

pip install virtualenv
pip install virtualenvwrapper

创建虚拟环境

cd /code/mycode/python/project
virtualenv venv

激活虚拟环境

source venv/bin/activate

退出虚拟环境

deactivate

安装框架
进入到虚拟环境中

pip install django==3.2.9

创建项目

django-admin startproject project
cd project
python manage.py runserver

浏览器中输入 http://127.0.0.1:8000/

退出运行模式Ctrl+c

创建应用

django-admin startapp blog

全局变量
使用Visual Studio Code工具打开project文件夹

4 编码实现 4.1 项目调整 4.1.1 修改语言时区

project/project/settings.py

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

调整为

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True

英文调整为中文,时区UTC调整为亚洲/上海。

4.1.2 添加应用路由

新增文件

project/blog/urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name = 'index'),
]
4.1.3 添加项目路由

编辑文件

project/project/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
]
4.1.4 添加应用视图

编辑文件

project/blog/views.py

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello,You're at the blog index.")

运行查看

python manage.py runserver

浏览器中输入 http://127.0.0.1:8000/blog/

4.1.5 生成迁移文件
python manage.py migrate

4.1.6 项目中添加应用

编辑文件

project/project/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'blog.apps.BlogConfig',
]
4.2 模型 4.2.1 编辑项目模型

project/blog/models.py

from django.db import models

# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=70)
    created_date = models.DateTimeField('创建时间',auto_now_add=True)
    updated_date = models.DateTimeField('修改时间',auto_now=True)

    def __str__(self):
        return self.name
        

class Tag(models.Model):
    name = models.CharField(max_length=70)
    created_date = models.DateTimeField('创建时间',auto_now_add=True)
    updated_date = models.DateTimeField('修改时间',auto_now=True)

    def __str__(self):
        return self.name


class Article(models.Model):
    STATUS_CHOICES = (
        ('d','Draft'),
        ('p','Published'),
    )
    title = models.CharField('文章标题',max_length=70)
    description = models.CharField('摘要',max_length=255)
    content = models.TextField('文章内容')
    created_date = models.DateTimeField('创建时间',auto_now_add=True)
    updated_date = models.DateTimeField('修改时间',auto_now=True)
    author = models.CharField('文章作者',max_length=70)
    views = models.PositiveIntegerField('浏览量',default=0)
    likes = models.PositiveIntegerField('点赞数',default=0)
    topped = models.BooleanField('置顶',default=False)
    status = models.CharField('文章状态', max_length=1,choices=STATUS_CHOICES)
    image = models.CharField('文章图片',max_length=255)
    category = models.ForeignKey('Category',verbose_name='分类',null=True,on_delete=models.SET_NULL)
    tag = models.ForeignKey('Tag',verbose_name='标签',null=True,on_delete=models.SET_NULL)

    def __str__(self):
        return self.title

    class meta:
        ordering = ['-updated_date']
   
class Banner(models.Model):
    text_title = models.CharField('图片标题',max_length=50,default='')
    text_info = models.CharField('图片文本', max_length=255)
    img = models.ImageField('轮播图', upload_to='banner/')
    link_url = models.CharField('图片链接', max_length=255)
    is_active = BooleanField('图片状态',default=False)

    def __str__(self):
        return self.text_title

    class meta:
        verbose_name = '轮播图'
        verbose_name_plural='轮播图'
4.2.2 生成模型文件

执行生成模型命令

(venv) j@T:~/code/python/project$ python manage.py makemigrations blog
Migrations for 'blog':
  blog/migrations/0001_initial.py
    - Create model Banner
    - Create model Category
    - Create model Tag
    - Create model Article

查看模型文件

blog/migrations/0001_initial.py

执行数据迁移

(venv) j@TK:~/code/python/project$ python manage.py migrate blog
Operations to perform:
  Apply all migrations: blog
Running migrations:
  Applying blog.0001_initial... OK

查看生成的数据库表

(venv) j@T:~/code/python/project$ python manage.py sqlmigrate blog 0001
BEGIN;
--
-- Create model Banner
--
CREATE TABLE "blog_banner" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text_title" varchar(50) NOT NULL, "text_info" varchar(255) NOT NULL, "img" varchar(100) NOT NULL, "link_url" varchar(255) NOT NULL, "is_active" bool NOT NULL);
--
-- Create model Category
--
CREATE TABLE "blog_category" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(70) NOT NULL, "created_date" datetime NOT NULL, "updated_date" datetime NOT NULL);
--
-- Create model Tag
--
CREATE TABLE "blog_tag" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(70) NOT NULL, "created_date" datetime NOT NULL, "updated_date" datetime NOT NULL);
--
-- Create model Article
--
CREATE TABLE "blog_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(70) NOT NULL, "description" varchar(255) NOT NULL, "content" text NOT NULL, "created_date" datetime NOT NULL, "updated_date" datetime NOT NULL, "author" varchar(70) NOT NULL, "views" integer unsigned NOT NULL CHECK ("views" >= 0), "likes" integer unsigned NOT NULL CHECK ("likes" >= 0), "topped" bool NOT NULL, "status" varchar(1) NOT NULL, "img" varchar(100) NULL, "category_id" bigint NULL REFERENCES "blog_category" ("id") DEFERRABLE INITIALLY DEFERRED, "tag_id" bigint NULL REFERENCES "blog_tag" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "blog_article_category_id_7e38f15e" ON "blog_article" ("category_id");
CREATE INDEX "blog_article_tag_id_4c94be52" ON "blog_article" ("tag_id");
COMMIT;
(venv) j@T:~/code/python/project$ 

注册

from django.contrib import admin
from . models import Article, Tag, Banner, Category
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,      {'fields': ['title']}),
        (None,    {'fields': ['description']}),
        (None,    {'fields': ['content']}),
        (None,    {'fields': ['author']}),
        (None,    {'fields': ['topped']}),
        (None,    {'fields': ['img']}),
        (None,    {'fields': ['status']}),
    ]
admin.site.register(Article, ArticleAdmin)
4.3 视图 4.3.1 前端视图

project/blog/views.py

from blog.models import Article, Category, Tag
from django.views.generic import ListView
import markdown2

# Create your views here.
class IndexView(ListView):
    template_name = "index.html"
    context_object_name = "article_list"
 
    def get_queryset(self):
        article_list = Article.objects.filter(status='p')
        for article in article_list:
            article.content = markdown2.markdown(article.content,)
        return article_list

    def get_context_data(self,**kwargs):
        kwargs['category_list'] = Category.objects.all().order_by('name')
        return super(IndexView,self).get_context_data(**kwargs)

在views.py文章有一个index.html文件
在project/blog目录下创建templates(存放index.html/detail.html)文件夹和static(存储css和js)文件夹,在index.html和detail.html文件中引入css和js文件。

project/blog/templates/blog/index.html

{% load static %}


  
    
 
 
     
    
  
 

编辑应用路由信息

/project/blog/urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('',views.IndexView.as_view(), name='index'),

浏览器中输入http://127.0.0.1:8000/blog/

以上信息为静态模板信息,后面需要管理后台维护到数据库信息,然后页面读取

4.3.2 后台页面

文章维护页面
在维护页面中可以对文章的内容、分类、标签、轮播图进行新增、编辑的维护管理

project/blog/admin.py

from django.contrib import admin
from . models import Article, Tag, Banner, Category
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,      {'fields': ['title']}),
        (None,    {'fields': ['description']}),
        (None,    {'fields': ['content']}),
        (None,    {'fields': ['author']}),
        (None,    {'fields': ['img']}),
        (None,    {'fields': ['category','tag','status','topped']}),
    ]
admin.site.register(Article, ArticleAdmin)

class CategoryAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,  {'fields': ['name']}),
    ]
admin.site.register(Category,CategoryAdmin)

class TagAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,  {'fields': ['name']}),
    ]
admin.site.register(Tag,TagAdmin)

class BannerAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,  {'fields': ['text_title']}),
        (None,  {'fields': ['text_info']}),
        (None,  {'fields': ['img']}),
        (None,  {'fields': ['link_url']}),
        (None,  {'fields': ['is_active']}),
    ]
admin.site.register(Banner,BannerAdmin)

后台页面显示
执行

python manage.py runserver

浏览器中输入http://127.0.0.1:8000/admin/
输入创建的管理员账号
登录后首页

文章维护页面

分类页面

标签页面

轮播图页面

手动后台维护分类、标签和文章信息。

原计划把编码整个在一篇中介绍,写了一部分后篇幅原因,随一分为二,下一篇中着手介绍视图读取数据库信息。

参考链接

Django博客开发教程
django 博客开发(一)
Django博客开发实战:开篇

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5684944.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存