Django简单博客实战(一)--- 项目创建

建立项目结构

项目地址:https://github.com/ylpxzx/lifeblog

建立Django项目

虚拟环境创建(终端环境cmd下)

  • 自行找个合适的位置建立python虚拟环境,避免与其他项目环境产生冲突(前提是已安装了虚拟环境库)
    # life_blog_venv为虚拟环境名
    python -m venv life_blog_venv
    
  • 进入虚拟环境
    • 进入Scripts目录
    • 输入activate.bat,回车

Django项目创建

  • 进入虚拟环境后,回到life_blog_venv项目目录里,安装Django
    pip install Django
    
  • 创建Django项目,项目名为lifeblog
    django-admin startproject lifeblog
    
  • 进入lifeblog文件夹,创建app应用
    python manage.py startapp post
    python manage.py startapp blogger
    
  • 将app名添加到settings.py中的INSTALLED_APPS列表(settings.py位于与项目同名的内部文件夹中)
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'blogger', # 添加该行
        'post', # 添加该行
    ]
    
  • 创建配置文件夹conf(用于存放配置文件):该文件夹与manage.py同级
  • 创建static文件夹(用于存放静态文件和静态模板):该文件夹与manage.py同级
  • 在static文件夹中分别创建以下三个文件夹
    • media:用于存放图片
    • static:用于存放静态文件(css、js文件等)
    • template:用于存放静态模板(html文件)

Django项目整体结构图

图中的whoosh_index文件夹将在后续步骤中建立。而comment不需要建立。.idea文件夹为开发工具生产的文件夹,无需自行建立。
在这里插入图片描述

项目汉化

修改settings.py文件中的相关配置

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

配置静态文件路径

在settings.py文件中添加相关配置

STATIC_URL = '/static/'

# 配置ImageFile字段图片上传路径
MEDIA_URL = '/media/'  # # 用于指定url路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media')  # 用于指定上传文件的存储路径

if DEBUG == False:
    STATIC_ROOT = os.path.join(BASE_DIR,'collected_static') # 用于在(debug=False)生产环境下加载静态文件。
    # 参数:自动在项目根目录创建collected_static目录用于存放移过来静态文件(在生产环境下执行python manage.py collectstatic时,会自动创建collected_static目录)

# 配置静态文件路径
STATICFILES_DIRS=(
    os.path.join(BASE_DIR,'static','static'),
)

在(内部lifeblog文件下)根urls.py文件添加如下代码

from django.contrib import admin
from django.urls import path
from django.conf.urls import include,url
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns  # 加入该行,如若不加,在生产环境下无法加载样式
from django.views.static import serve   # 加入该行,如若不加,在生产环境下无法加载样式

urlpatterns = [
    path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # 用于上传和显示图片

urlpatterns += staticfiles_urlpatterns()  # # 加入该行,如若不加,在生产环境下可能无法加载样式

if settings.DEBUG == False:
    print('当前处于生产环境下')
    urlpatterns += [
        url(r'^static/(?P<path>.*)$',serve,{'document_root':settings.STATIC_ROOT}), # 加入该行,如若不加,在生产环境下无法加载样式
        url(r'^media/(?P<path>.*)$',serve,{'document_root':settings.MEDIA_ROOT}),  # 加入该行,如若不加,在生产环境下无法显示图片
        ]
else:
    print('当前处于开发环境下')

配置模板文件路径

修改settings.py文件中的相关配置

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'static','template')], # 添加该行
        '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',
            ],
            'builtins':['django.templatetags.static'], # 添加该行,设置该行后,不需要在静态模板文件中显示使用{% load static %}
        },
    },
]

配置MySQL数据库

记得先在MySQL中创建用到的数据库,这里我们使用的数据库名为lifeblog_database。

这里我们采用读取配置文件的方式来设置MySQL数据库信息,比较安全。

  • 在conf文件夹下建立以下两个文件
    • config.ini
    • config_read.py

config.ini文件内容

[MySQL]
host=localhost
user=root
password=数据库密码
db=lifeblog_database
charset=utf8
port=3306

config_read.py 文件内容
注意:需先在虚拟环境下安装第三方库configparser

pip install configparser

import configparser
import os

project_dir = os.path.dirname(os.path.abspath('conf'))  # 获取当前文件的目录
config_path = os.path.join(project_dir, "conf", "config.ini")
cf = configparser.ConfigParser()
cf.read(config_path)  # 读取配置文件

# secs = cf.sections()   # 获取ini文件中的所有section,并以列表形式返回

# mysql_options = cf.options("MySQL") #获取某个section名所对应的键

# mysql_items = cf.items("MySQL")  # 获取section对应的全部键值对

host = cf.get("MySQL", "host")
user = cf.get("MySQL", "user")
password = cf.get("MySQL", "password")
db = cf.get("MySQL", "db")
charset = cf.get("MySQL", "charset")
port = cf.get("MySQL", "port")

sql = {
    'HOST' : host,
    'USER' : user,
    'PASSWORD' : password,
    'DB' : db,
    'CHARSET' : charset,
    'PORT' : port
}

修改settings.py文件下的DATABASES。

# MySQL数据库配置
from conf.config_read import sql  # 读取配置文件
DATABASES = {
    'default':{
        'ENGINE': 'django.db.backends.mysql',
        'NAME': sql['DB'], # 数据库名称
        'USER': sql['USER'], # 数据库用户
        'PASSWORD': sql['PASSWORD'], # 数据库密码
        'HOST': sql['HOST'], # 数据库ip
        'PORT': sql['PORT'], # 数据库端口
    }
}

app模型字段创建

在前面,我们建立了blogger和post两个应用,在应用文件夹下会生成多个py文件,模型字段的定义在models.py文件中创建,用于映射(ORM)到数据库中,创建相应的数据表。

定义数据字段
blogger和post文件夹下的models.py中写入如下代码

  • blogger/models.py
from django.db import models
from ckeditor.fields import RichTextField
# Create your models here.
class Blogger(models.Model):
    '''博主信息模型'''
    name = models.CharField('博主名',default='狼性书生',max_length=20)
    head_photo = models.ImageField('头像', upload_to='blog_img',null=True,blank=True,default='/cover_img/default.jpg')
    blog_major = models.CharField('职业',default='程序猿',max_length=20)
    autograph = RichTextField('个性签名',default='个性签名')
    blog_email = models.EmailField('博主邮箱',default='794859685@qq.com')

    def __str__(self):
        return self.name

class Link(models.Model):
    '''博主链接模型'''
    icon_name = models.CharField("链接图标",max_length=50,default='fa fa-dribbble')
    link_name = models.CharField("链接",max_length=50)
    blogger = models.ForeignKey('Blogger',on_delete=models.CASCADE,related_name='blogger_link')

    def __str__(self):
        return self.link_name


class Layout(models.Model):
    '''网站配置模型'''
    # main_image = models.ImageField("首页图",upload_to='layout_img',default='/layout_img/home-banner.jpg')
    logo_image = models.ImageField("Logo",upload_to='layout_img',default='/layout_img/favicon.ico')
    website_name = models.CharField("网站标题名",max_length=20,default='Mr Wolf Blog')

    def __str__(self):
        return self.website_name
  • post/models.py
    在static/media文件下创建cover_img文件夹,用于存放文章封面
import os
import time
import datetime
from django.db import models
# Create your models here.

def modify_path(instance, filename):
    '''
    重定义封面保存路径
    :param instance: self
    :param filename: 文件名
    :return: 新路径
    '''
    ext = filename.split('.').pop()
    now_date = datetime.datetime.now().strftime('%Y%m%d')
    now_time = int(time.time())
    filename = '{0}{1}.{2}'.format(now_date, now_time, ext)
    return os.path.join('cover_img', now_date, filename) # 系统路径分隔符差异,增强代码重用性

class Post(models.Model):
    '''
    文章模型
    '''
    title = models.CharField('标题',max_length=100,default='无标题名',null=True,blank=True)
    cover = models.ImageField('封面', upload_to=modify_path,null=True,blank=True,default='/cover_img/default.jpg')
    create_time = models.DateTimeField('创建时间',auto_now=True)
    content = models.TextField('文章内容',default='文章内容')
    is_publish = models.BooleanField(default=False)
    is_comment = models.BooleanField(default=False)
    total_views = models.PositiveIntegerField('文章浏览量',default=0)
	
	# 文章与分类:多对一关系。在多的一方定义ForeignKey字
    category = models.ForeignKey('Category',on_delete=models.CASCADE,related_name='post')

    def __str__(self):
        return self.title
        
    # 完善后台数据显示过长情况
    def short_detail(self):
        if len(str(self.content)) > 30:
            return '{}...'.format(str(self.content)[0:29])
        else:
            return str(self.content)
    short_detail.allow_tags = True
    short_detail.short_description = u'文章内容'
    
class Category(models.Model):
    post_category = models.CharField('文章类别',max_length=20,default='杂记')
    def __str__(self):
        return self.post_category

将模型字段注册到admin后台

创建超级用户

虚拟环境、manage.py所在目录下执行如下指令

python manage.py createsuperuser
# 输入用户名、密码,邮箱可不填
注册字段到Admin后台
  • post/admin.py
from django.contrib import admin
from .models import Post,Category
from django.utils.safestring import mark_safe
# Register your models here.

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ['title','image_data','create_time','short_detail','is_publish','is_comment','category','id']
    list_editable = ['is_publish','is_comment','category']
    list_filter = ['title','create_time','is_publish','is_comment','category']
    # readonly_fields = ('image_data',)  
    
    # 缩略图显示
    def image_data(self,obj):
        return mark_safe(u'<img src="%s" width="100px" />' % obj.cover.url)
    image_data.short_description = u'封面'

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ['id','post_category']
    list_editable = ['post_category']
  • blogger/admin.py
from django.contrib import admin
from .models import Blogger,Link,Layout
from django.utils.safestring import mark_safe

admin.site.site_title="Mr Wolf Blog"
admin.site.site_header="Mr Wolf博客管理系统"

@admin.register(Blogger)
class BloggerAdmin(admin.ModelAdmin):
    list_display = ['id','name','image_data','blog_major','autograph','blog_email']
    list_editable = ['name','blog_major','blog_email']

    # 缩略图,后台展示页显示缩略图
    def image_data(self,obj):
        return mark_safe(u'<img src="%s" width="100px" />' % obj.head_photo.url)
    image_data.short_description = u'头像'

@admin.register(Link)
class LinkAdmin(admin.ModelAdmin):
    list_display = ['id','link_name','icon_name']
    # list_editable = ['link_name']

@admin.register(Layout)
class LayoutAdmin(admin.ModelAdmin):
    list_display = ['id', 'logo_img', 'website_name']
    list_editable = ['website_name']

    def logo_img(self,obj):
        return mark_safe(u'<img src="%s" width="100px" />' % obj.logo_image.url)
    logo_img.short_description = u'logo'

数据库迁移

虚拟环境、manage.py所在目录下执行如下指令

python manage.py makemigrations # 记录App下models的变更记录,生成migrations文件,可查看文件内的py文件的内容
python manage.py migrate  # 同步迁移的记录

迁移过程中可能会报错,比如pillow库未找到等,这是未导入第三方库的原因,可根据报错信息,缺什么就"pip install 什么库"。

或者pip install -r requirements.txt,前提是拉取github上本项目的requirements.txt文件。
其他异常解决方法

  • ImportError: cannot import name ‘six’ from 'django.utils’异常

    • 安装six
    pip install six
    
    • 将Lib/site-packages/six.py复制到Lib/site-packages/django/utils

  • ImportError: cannot import name python_2_unicode_compatible异常

    • 报错地方导入的包替代为以下导入语句
    from django.utils.six import python_2_unicode_compatible
    

启动Django

虚拟环境、manage.py所在目录下执行如下指令

python manage.py runserver

浏览器进入http://127.0.0.1:8000/admin
登录进去后,是比较简陋的界面,后续将对其进行美化。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狼性书生

谢谢鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值