本文共 10076 字,大约阅读时间需要 33 分钟。
项目地址:https://github.com/ylpxzx/lifeblog
# life_blog_venv为虚拟环境名python -m venv life_blog_venv
pip install Django
django-admin startproject lifeblog
python manage.py startapp postpython manage.py startapp blogger
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blogger', # 添加该行 'post', # 添加该行]
图中的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 adminfrom django.urls import pathfrom django.conf.urls import include,urlfrom django.conf import settingsfrom django.conf.urls.static import staticfrom 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.*)$',serve,{ 'document_root':settings.STATIC_ROOT}), # 加入该行,如若不加,在生产环境下无法加载样式 url(r'^media/(?P .*)$',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中创建用到的数据库,这里我们使用的数据库名为lifeblog_database。
这里我们采用读取配置文件的方式来设置MySQL数据库信息,比较安全。
config.ini文件内容
[MySQL]host=localhostuser=rootpassword=数据库密码db=lifeblog_databasecharset=utf8port=3306
config_read.py 文件内容
注意:需先在虚拟环境下安装第三方库configparserpip install configparser
import configparserimport osproject_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'], # 数据库端口 }}
在前面,我们建立了blogger和post两个应用,在应用文件夹下会生成多个py文件,模型字段的定义在models.py文件中创建,用于映射(ORM)到数据库中,创建相应的数据表。
定义数据字段
blogger和post文件夹下的models.py中写入如下代码from django.db import modelsfrom 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.nameclass 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_nameclass 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
import osimport timeimport datetimefrom 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
虚拟环境、manage.py所在目录下执行如下指令
python manage.py createsuperuser# 输入用户名、密码,邮箱可不填
from django.contrib import adminfrom .models import Post,Categoryfrom 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'' % obj.cover.url) image_data.short_description = u'封面'@admin.register(Category)class CategoryAdmin(admin.ModelAdmin): list_display = ['id','post_category'] list_editable = ['post_category']
from django.contrib import adminfrom .models import Blogger,Link,Layoutfrom django.utils.safestring import mark_safeadmin.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'' % 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'' % 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’异常
pip install six
ImportError: cannot import name python_2_unicode_compatible异常
from django.utils.six import python_2_unicode_compatible
虚拟环境、manage.py所在目录下执行如下指令
python manage.py runserver
浏览器进入http://127.0.0.1:8000/admin
登录进去后,是比较简陋的界面,后续将对其进行美化。转载地址:http://kgugn.baihongyu.com/