前言

本章主要讲述基于Django框架上,搭建一个比较简单的个人博客

ps:觉得页面太丑了的话大家可以自己优化,前端我这里没套框架直接用的原生css+html
我的审美止于此了 - -


环境:

  • python 3.6
  • Pycharm
  • Django 2.0.13
  • mysql 5.7


一、Django框架介绍

1、创建Django项目

  • 直接在pycharm里新建一个Django项目即可

在这里插入图片描述


2、框架简要介绍

  • 创建完后会自动生成Django的框架,那我们这part就简单介绍一下各个文件是干啥的

在这里插入图片描述


二、框架搭建

1、后台搭建

1.1)settings.py

在这里插入图片描述

"""
Django settings for MyDjango project.

Generated by 'django-admin startproject' using Django 3.2.13.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = 'django-insecure-^p87-rpgr!ujeb6+9&3n_5dj*(h9313n8801uss$vvwloqic_z'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 应用配置
    'MyBlog.apps.MyblogConfig',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'MyDjango.urls'

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',
            ],
        },
    },
]

WSGI_APPLICATION = 'MyDjango.wsgi.application'

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

# 1、改为你自己的数据库配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'myblog',
        'USER': 'root',
        'PASSWORD': 'yy1998123',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

1.2)model.py
"""
    数据库表模型类
"""
from __future__ import unicode_literals
from django.db import models


class Category(models.Model):
    """
    博客分类
    """
    name = models.CharField('名称', max_length=30)

    class Meta:
        verbose_name = "类别"
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return self.name


class Tag(models.Model):
    """
    博客标签
    """
    name = models.CharField('名称', max_length=16)

    class Meta:
        verbose_name = "标签"
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return self.name


class Blog(models.Model):
    """
    博客
    """
    title = models.CharField('标题', max_length=32)
    author = models.CharField('作者', max_length=16)
    content = models.TextField('内容')
    pub = models.DateField('发布时间', auto_now_add=True)
    # on_delete解释:当子表中的某条数据删除后,关联的外键操作
    # on_delete = models.SET_NULL
    # 置空模式,删除时,外键字段被设置为空,前提就是blank=True, null=True,定义该字段时,允许为空。
    # 理解:删除关联数据(子表),与之关联的值设置默认值为null(父表中),这个前提需要父表中的字段可以为空。
    category = models.ForeignKey(Category, verbose_name='分类', on_delete=None)  # 多对一(博客--类别)
    # 多对多关系,没有on_delete参数
    tag = models.ManyToManyField(Tag, verbose_name='标签')  # (多对多)

    class Meta:
        verbose_name = "博客"
        verbose_name_plural = verbose_name

    def __unicode__(self):
        return self.title


class Comment(models.Model):
    """
    博客评论
    """
    blog = models.ForeignKey(Blog, verbose_name='博客', on_delete=None)  # (博客--评论:一对多)
    name = models.CharField('称呼', max_length=16)
    email = models.EmailField('邮箱')
    content = models.CharField('内容', max_length=240)
    pub = models.DateField('发布时间', auto_now_add=True)

    class Meta:
        verbose_name = "评论"
        verbose_name_plural = "评论"

    def __unicode__(self):
        return self.content

1.3)admin.py
"""
    # Register your models here.
    django自带的后台管理系统
    在这儿注册你的模型
"""
from django.contrib import admin
from .models import *


class CategoryAdmin(admin.ModelAdmin):
    list_display = ('name',)


class TagAdmin(admin.ModelAdmin):
    list_display = ('name',)


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'content', 'pub')


class CommentAdmin(admin.ModelAdmin):
    list_display = ('blog', 'name', 'content', 'pub')


admin.site.register(Category, CategoryAdmin)
admin.site.register(Tag, TagAdmin)
admin.site.register(Blog, BlogAdmin)
admin.site.register(Comment, CommentAdmin)

1.4)创建数据库及字段
# teminal输入命令
python manage.py makemigrations
python manage.py migrate

# 创建管理员用户
python manage.py createsuperuser

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


1.5)后台管理员模块展示
  • 访问127.0.0.1:8000/admin即可查看后台管理系统

在这里插入图片描述

在这里插入图片描述


2、前台搭建

2.1)views.py
"""
    视图函数
    注意所有的视图函数需要在urls中进行配置
"""
from django.shortcuts import render, render_to_response

from .models import *

from .forms import CommentForm
from django.http import Http404


def get_blogs(request):
    # 获得所有的博客按发布时间降序排
    blogs = Blog.objects.all().order_by('-pub')
    # 传递context:blog参数到固定页面
    return render_to_response('blog_list.html', {'blogs': blogs})


def get_details(request, blog_id):
    # 检查异常
    try:
        blog = Blog.objects.get(id=blog_id)  # 获取固定的blog_id的对象;
    except Blog.DoesNotExist:
        raise Http404

    if request.method == 'GET':
        form = CommentForm()
    else:  # 请求方法为Post
        form = CommentForm(request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            cleaned_data['blog'] = blog
            Comment.objects.create(**cleaned_data)
    ctx = {
        'blog': blog,
        'comments': blog.comment_set.all().order_by('-pub'),
        'form': form
    }  # 返回3个参数
    return render(request, 'blog_details.html', ctx)

2.2)urls.py
"""
    配置文件路由
"""
from django.conf.urls import url
from django.contrib import admin
from django.urls import path

from MyBlog.views import get_blogs, get_details

urlpatterns = [
    # path(..)是Django2.0的写法,url(...)是Django1.0的写法
    path('admin/', admin.site.urls),
    url(r'^blog/$', get_blogs),
    url(r'^detail/(\d+)/$', get_details, name='blog_get_detail'),
]

2.3)forms.py
  • 因为我们想要实现博客的评论功能,所以我们新增一个forms.py

在这里插入图片描述

"""
    博客的评论功能
"""
from django import forms


class CommentForm(forms.Form):
    name = forms.CharField(label='昵称', max_length=16, error_messages={
        'required': '请填写您的昵称',
        'max_length': '昵称太长,请重新修改!'
    })
    email = forms.EmailField(label='邮箱', error_messages={
        'required': '请填写您的邮箱',
        'invalid': '邮箱格式不正确'
    })
    content = forms.CharField(label='内容', error_messages={
        'required': '请填写您的评论内容!',
        'max_length': '评论内容太长咯'
    })



3、模板页面

在这里插入图片描述

3.1)blog_list.html
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Mikasa的博客</title>
    <style type="text/css">
        body {
            color: #efd;
            background: #8d8a8a;
            padding: 12px 5em;
            margin: 7px;
        }

        h1 {
            margin-top: -10px;
            padding: 2em;
            background: #4e583b;
        }

        h2 {
            color: #4e583b;
            border-top: 1px dotted #fff;
            margin-top: 2em;
            padding-top:15px;
        }
        a {
            text-decoration:none;
        }
        .blog {
            padding: 20px 0px;
        }

        .blog .info span {
            padding-right: 10px;
        }

        .blog .summary {
            padding-top: 20px;
        }
         p {
            text-indent:2em
        }
    </style>
</head>
<body>
<div class="header">
    <h1 align="center">Mikasa的博客</h1>
</div>
<h3 style="margin-bottom: -50px;font-size: x-large;">博客列表
</h3>
<hr/>
{% for blog in blogs %}
    <div align="center" class="blog">
        <div class="title">
            <a href="{% url 'blog_get_detail' blog.id %} "dec>
                <h2 align="left" >{{ blog.title }}</h2>
            </a>
        </div>

        <div class="info" align="left">
            <span class="category" style="color: #eeccad;">{{ blog.category.name }}</span>
            <span class="author" style="color: #2964af;">{{ blog.author }}</span>
            <span class="pub" style="color: #90d56b">{{ blog.pub }}</span>
        </div>
        <div class="summary">
            <p align="left">
                {{ blog.content | truncatechars:100 }}
            </p>
        </div>

    </div>
{% endfor %}
</body>
</html>

3.2)blog_details.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ blog.title }}</title>
    <style type="text/css">
        .blog {
            padding: 20px 0px;
        }

        .blog .info span {
            padding-right: 10px;

        }

        .blog .summary {
            padding-top: 20px;
        }

        body {
            color: #efd;
            background: #8d8a8a;
            padding: 12px 5em;
            margin: 7px;
        }

        h1 {
            margin-top: -10px;
            padding: 2em;
            background: #4e583b;
            color: #eeffdd;
        }

        h2 {
            color: #4e583b;
        {#border-top: 1px dotted #fff;#} margin-top: 2em;
            padding-top: 15px;
        }

        a {
            text-decoration: none;
        }

        span {
            font-size: 18px;
            line-height: 2em;
        }

        p {
            text-indent:2em
        }
    </style>
</head>
<body>
<div class="header">
    <div class="title" align="center">
        <a href="#"><h1>{{ blog.title }}</h1></a>
    </div>
</div>

<div class="content">
    <div class="blog">
        <div class="info" align="center">
            <span class="category" style="color: #eeccad;" border="10px" >{{ blog.category.name }}</span>
            <span class="author" style="color: #2964af;">{{ blog.author }}</span>
            <span class="pub" style="color: #90d56b">{{ blog.pub }}</span>
        </div>
        <p class="summary">
            {{ blog.content }}
        </p>
        <div class="comment">
            <div class="comment-diaplay" style="padding-top: 1cm;">
                <h3 >评论</h3>
                {% for comment in comments %}
                    <div class="comment-field" style="padding-top: 10px; color: #49491a">
                        {{ comment.name }}说:{{ comment.content }}
                    </div>
                {% endfor %}
            </div>
            <div class="comment-post" style="padding-top: 20px ;">
                <h3>提交评论</h3>
                <form action="{% url 'blog_get_detail' blog.id %}" method="post">
                    {% csrf_token %}
                    {% for field in form %}
                        <div class="input-field" style="padding-top: 10px;">
                            {{ field.label }}{{ field }}
                        </div>
                        <div class="error" style="color: #ff0000;">
                            {{ field.errors }}
                        </div>
                    {% endfor %}
                    <button type="submit" style="margin-top:20px ">提交</button>
                    <button type="reset" style="margin-top:20px ">重置</button>
                </form>
            </div>
        </div>
    </div>
</div>
</body>
</html>

三、运行项目及展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐