开发流程介绍
之前Django的学习过程当中已经把基本Django开发学完了,现在以Django 的博客项目完成一遍课程的回顾和总结。同时来一次完整开发的Django体验。
一个产品从研究到编码我们要经历以下的过程:
博客开发需求分析与建模
需求分析
本次项目完成的是一个博客的项目,博客主要目的是为了分享个人的技术,进行技术积累。
主要是发布文章日志。但是也需要有评论和互动。需要完成以下功能点:
1、文章的发布、展示、修改、删除。
2、文章评论
3、读者互动
4、图片管理
概要设计
我们对上面的四个需求进行详细的分析
1、文章的发布、展示、修改、删除。
文章发布、修改和删除,我们可以通过Django的admin后台完成,当然也可以自己定义或者用三方的后台比如xadmin,这个可以作为版本迭代的一个方向。
但是在开始的开发过程当中,我们着重要做的就是展示功能,文章展示通常分为以下几个技术点:
1、文章列表页
按类型划分
搜索
分页
2、文章详情页
文章排版
2、文章评论
1、评论发布
2、评论回复
3、读者互动
提供个人联系方式
4、图片管理
1、文章图片展示管理
2、照片展示管理
完成分析之后,开始创建Django项目
开发版本:
Python 3.5
Django 1.8.2
pillow 模块 pip3 install pillow
django-ckeditor 模块 pip3 install django-ckeditor
Pycharm
1、创建项目
命令:django-admin startproject OurBlog
2、切入项目,创建功能,app
命令:python manage.py startapp Article
3、创建模板和静态文件存放的位置
4、安装上述依赖模块
注:如果是和我一样python2和python3都安装在一个系统下的话,就用pip3,否则用pip就可以
命令:pip3 install pillow
命令:pip3 install django-ckeditor
数据建模
数据建模:数据建模就是用数据库描述上面分析的博客需求,然后形成对应的表和关系,数据建模是web开发至关总要的一个环节,一个优秀的模型是web开发成功的一 大半。
通常的web开发会使用数据库语句,在数据库当中搭建模型,这样开发很直观,但是无疑增加了开发的难度,Django采用的是orm(数据库映射)用Python类描述数据 库,然后通过orm将描述映射到数据当中。Django的模型文件是应用(APP)的models.py
OurBlog/Article/models.py
1 from django.db import models 2 from ckeditor_uploader.fields import RichTextUploadingField 3 4 class Author(models.Model): 5 gender_choice = ( 6 ("M","Male"), 7 ("F","Female"), 8 ) 9 name = models.CharField(max_length = 32,verbose_name = "作者姓名") 10 age = models.IntegerField(verbose_name = "作者年龄",blank = True,null = True) 11 gender = models.CharField(max_length = 2,choices = gender_choice,verbose_name = "作者性别",blank = True,null = True) 12 email = models.EmailField(verbose_name = "作者邮箱",blank = True,null = True) 13 phone = models.CharField(max_length = 11,verbose_name = "作者电话",blank = True,null = True) 14 photo = models.ImageField(verbose_name = "作者头像",upload_to = "images/author") 15 16 def __str__(self): 17 return "作者:%s"%self.name 18 19 class Classify(models.Model): 20 label = models.CharField(max_length = 32,verbose_name = "分类标签") 21 description = models.TextField(verbose_name = "分类描述") 22 23 def __str__(self): 24 return "标签:%s" % self.label 25 26 class Comment(models.Model): 27 content = RichTextUploadingField(verbose_name = "评论内容") 28 content_name = models.CharField(max_length = 32,verbose_name = "评论用户") 29 agree = models.IntegerField(verbose_name = "评论点赞") 30 time = models.DateTimeField(verbose_name = "评论时间") 31 32 def __str__(self): 33 return "[%s] 评论: %s"%(self.content_name,self.content) 34 35 36 class Picture(models.Model): 37 label = models.CharField(max_length = 32, verbose_name = "图片标签") 38 image = models.ImageField(verbose_name = "图片链接", upload_to = "images/picture") 39 description = RichTextUploadingField(verbose_name = "图片描述") 40 41 classify = models.ForeignKey(to = Classify, verbose_name = "图片分类") 42 commant = models.ForeignKey(to = Comment, verbose_name = "图片评论") 43 44 def __str__(self): 45 return "图片名称: %s" % self.label 46 47 class Article(models.Model): 48 """ 49 一篇文章可以有一个作者,一个作者可以以有一篇文章, 50 一篇文章有多条评论 51 一个文章有多个分类 52 一个分类有多篇文章 53 """ 54 title = models.CharField(max_length = 32,verbose_name = "文章标题") 55 time = models.DateField(verbose_name = "文章发表日期") 56 description = RichTextUploadingField(verbose_name = "文章描述") 57 content = RichTextUploadingField(verbose_name = "文章内容") 58 59 picture = models.ImageField(verbose_name = "文章图片",upload_to = "images/article") 60 author = models.ForeignKey(Author) 61 classify = models.ManyToManyField(Classify) 62 commant = models.ForeignKey(to=Comment, verbose_name="文章评论", blank = True,null = True) #文章可以有评论,也可以没有 63 64 def __str__(self): 65 return "文章:%s" % self.title
完成模型的定义之后,接着进行项目的配置的修改
OurBlog/OurBlog/settings.py
1 #…… 2 # Application definition 3 #安装功能 4 INSTALLED_APPS = ( 5 ‘django.contrib.admin‘, 6 ‘django.contrib.auth‘, 7 ‘django.contrib.contenttypes‘, 8 ‘django.contrib.sessions‘, 9 ‘django.contrib.messages‘, 10 ‘django.contrib.staticfiles‘, 11 ‘Article‘, #我们自定义的功能 12 ‘ckeditor‘, #Django ckeditor的功能 13 ‘ckeditor_uploader‘, #Django ckeditor的上传功能 14 ) 15 #....... 16 #模板配置 17 TEMPLATES = [ 18 { 19 ‘BACKEND‘: ‘django.template.backends.django.DjangoTemplates‘, 20 ‘DIRS‘: [ 21 os.path.join(BASE_DIR,‘template‘) #模板配置 22 ], 23 ‘APP_DIRS‘: True, 24 ‘OPTIONS‘: { 25 ‘context_processors‘: [ 26 ‘django.template.context_processors.debug‘, 27 ‘django.template.context_processors.request‘, 28 ‘django.contrib.auth.context_processors.auth‘, 29 ‘django.contrib.messages.context_processors.messages‘, 30 ], 31 }, 32 }, 33 ] 34 35 WSGI_APPLICATION = ‘OurBlog.wsgi.application‘ 36 37 38 # Database 39 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases 40 #数据库配置,默认使用sqllite数据库 41 DATABASES = { 42 ‘default‘: { 43 ‘ENGINE‘: ‘django.db.backends.sqlite3‘, 44 ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), 45 } 46 } 47 48 49 # Internationalization 50 # https://docs.djangoproject.com/en/1.8/topics/i18n/ 51 #语言和时区配置 52 LANGUAGE_CODE = ‘zh-hans‘ #项目语言为中文 53 54 TIME_ZONE = ‘Asia/Shanghai‘ #调整为东8区时间,上海时间 55 56 USE_I18N = True 57 58 USE_L10N = True 59 60 USE_TZ = False #禁止采用0时区时间 61 62 63 # Static files (CSS, JavaScript, Images) 64 # https://docs.djangoproject.com/en/1.8/howto/static-files/ 65 66 #静态文件配置 67 STATIC_URL = ‘/static/‘ 68 STATICFILES_DIRS = ( 69 os.path.join(BASE_DIR,"static").replace("\\","/"), 70 ) 71 STATIC_ROOT = os.path.join(BASE_DIR,"static/ckeditor").replace("\\","/") 72 73 #媒体文件配置 我们上传图片使用 74 MEDIA_URL = "/media/" 75 MEDIA_ROOT = os.path.join(BASE_DIR,"static").replace("\\","/") 76 77 #ckeditor配置 78 CKEDITOR_UPLOAD_PATH = ‘uploads/‘ #上传路径 79 CKEDITOR_IMAGE_GACKEND = ‘pillow‘ #上传图片用的模块
然后进行ckeditor的路由指出。
OurBlog/OurBlog/urls.py
1 from django.conf.urls import include, url 2 from django.contrib import admin 3 4 urlpatterns = [ 5 #...... 6 url(r‘^ckeditor/‘, include(‘ckeditor_uploader.urls‘)), 7 ]
进行模型后台的安装
OurBlog/Article/admin.py
1 from django.contrib import admin 2 from Article.models import Article,Author,Classify,Picture,Comment 3 4 class ArticleAdmin(admin.ModelAdmin): 5 search_fields = ["title","time"] #添加搜索选项 6 7 admin.site.register(Article,ArticleAdmin) 8 admin.site.register(Author) 9 admin.site.register(Classify) 10 admin.site.register(Picture) 11 admin.site.register(Comment) 12 # Register your models here.
进行数据库的同步
1、校验配置是否正确
命令: python manage.py validate
2、生成数据库语句
命令: python manage.py makemigrations
3、完成数据库同步
命令: python manage.py syncdb
创建超级用户
注:只有在第一次同步数据库才会出现创建超级用户的选项,创建的是Django自带后台的超级用户,密码默认不显示,填写时候要小心
然后进行静态文件的收集
命令: python manage.py collectstatic
博客样式加载,模板渲染
上面的步骤完成之后,我们就可以进行页面的编写,加载,和渲染了,在工作当中,除非是个人项目,一般情况下,当进行Django开发的时候,前台的页面也就具备了。在这个项目当中,我们采用一个准备好的模板进行演示:
1、模板渲染的第一步,是打开模板文件,进行页面特征的查看,对结构相同的页面构建base结构。我们课上演示的是一款中国风格的博客模板,当然,大家也可以自 己定义或者下载自己喜欢的模板。(模板地址:链接:https://pan.baidu.com/s/1P2h8qwUcVoVA9R74nEm_pA 提取码:27x8 注:该模板不是作者开发,用于联系如 果盈利,请联系原作者 )
模板文件如下:
比对四个页面的效果发现:
顶部:
尾部:
效果一样。所以根据这个我们搭建自己的base页面。在这里要注意的是这套模板的编码是gb2312,我们需要进行修改。修改完成定制base页面
首先将静态文件迁入项目的static目录
然后根据前端样式分析,编写base.html(手生的同学可以复制一个页面过来,进行修改)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title> 6 {% block title %} 7 while 个人博客 8 {% endblock %} 9 </title> 10 <meta name="keywords" content="while 个人博客" /> 11 <meta name="description" content="while 个人博客" /> 12 <link href="/static/css/base.css" rel="stylesheet"> 13 <link href="/static/css/index.css" rel="stylesheet"> 14 <!--[if lt IE 9]> 15 <script src="/static/js/modernizr.js"></script> 16 <![endif]--> 17 <script type="text/javascript" src="/static/js/jquery.js"></script> 18 {% block style %} 19 {% endblock %} 20 </head> 21 <body> 22 23 <div id="wrapper"> 24 <header> 25 <div class="headtop"></div> 26 <div class="contenttop"> 27 <div class="logo f_l">大泽九章--个人博客</div> 28 <div class="search f_r"> 29 <form action="/e/search/index.php" method="post" name="searchform" id="searchform"> 30 <input name="keyboard" id="keyboard" class="input_text" value="请输入关键字" style="color: rgb(153, 153, 153);" onfocus="if(value==‘请输入关键字‘){this.style.color=‘#000‘;value=‘‘}" onblur="if(value==‘‘){this.style.color=‘#999‘;value=‘请输入关键字‘}" type="text"> 31 <input name="show" value="title" type="hidden"> 32 <input name="tempid" value="1" type="hidden"> 33 <input name="tbname" value="news" type="hidden"> 34 <input name="Submit" class="input_submit" value="搜索" type="submit"> 35 </form> 36 </div> 37 <div class="blank"></div> 38 <nav> 39 <div class="navigation"> 40 <ul class="menu"> 41 <li><a href="/index/">网站首页</a></li> 42 <ul> 43 <li><a href="bf/about.html">个人简介</a></li> 44 <li><a href="bf/listpic.html">个人相册</a></li> 45 </ul> 46 </li> 47 <li><a href="/Article/myBlog/">我的博客</a> 48 <ul> 49 <li><a href="bf/newslistpic.html">个人博客</a></li> 50 <li><a href="bf/newslistpic.html">技术博客</a></li> 51 </ul> 52 </li> 53 <li><a href="/Article/myPicture/">我的照片</a></li> 54 <li><a href="/aboutMe/">关于我</a> 55 <li><a href="#">给我留言</a> </li> 56 </ul> 57 </div> 58 </nav> 59 <SCRIPT type=text/javascript> 60 // Navigation Menu 61 $(function() { 62 $(".menu ul").css({display: "none"}); // Opera Fix 63 $(".menu li").hover(function(){ 64 $(this).find(‘ul:first‘).css({visibility: "visible",display: "none"}).slideDown("normal"); 65 },function(){ 66 $(this).find(‘ul:first‘).css({visibility: "hidden"}); 67 }); 68 }); 69 </SCRIPT> 70 </div> 71 </header> 72 {% block content %} 73 74 {% endblock %} 75 <footer> 76 <div class="footer"> 77 <div class="f_l"> 78 <p>All Rights Reserved 版权所有:<a href="http://www.yangqq.com">while 个人博客</a> 备案号:蜀ICP备00000000号</p> 79 </div> 80 <div class="f_r textr"> 81 <p>let‘s say hello world</p> 82 </div> 83 </div> 84 </footer> 85 </div> 86 </body> 87 </html>
然后开始继承base模板开始定义指出页面
首先定义视图文件
1 from django.shortcuts import render 2 3 def base(request): 4 return render(request,"base.html") 5 6 def index(request): 7 return render(request,"index.html") 8 9 def myArticle(request): 10 return render(request,"myArticle.html") 11 12 def myPicture(request): 13 return render(request,"myPicture.html") 14 15 def aboutMe(request): 16 return render(request,"aboutMe.html") 17 18 def connectMe(request): 19 return render(request,"aboutMe.html")
然后进行继承,完成基本的样式修改,我们以aboutMe页面为例
1 {% extends "base.html" %} 2 3 {% block title %} 4 关于我们 5 {% endblock %} 6 7 {% block style %} 8 <link href="/static/css/main.css" rel="stylesheet"> 9 {% endblock %} 10 11 {% block content %} 12 <div class="container"> 13 <div class="con_content"> 14 <div class="about_box"> 15 <h2 class="nh1"><span>您现在的位置是:<a href="/" target="_blank">网站首页</a>>><a href="#" target="_blank">信息浏览</a></span><b>个人简介</b></h2> 16 <div class="f_box"> 17 <p class="a_title">个人简介</p> 18 <p class="p_title"></p> 19 <!-- <p class="box_p"><span>发布时间:2017-07-07 15:12:42</span><span>作者:唐孝文</span><span>来源:稽查支队</span><span>点击:111056</span></p>--> 20 <!-- 可用于内容模板 --> 21 </div> 22 <ul class="about_content"> 23 <p> 人生就是一个得与失的过程,而我却是一个幸运者,得到的永远比失去的多。生活的压力迫使我放弃了轻松的前台接待,放弃了体面的编辑,换来虽有些蓬头垢面的工作,但是我仍然很享受那些熬得只剩下黑眼圈的日子,因为我在学习使用Photoshop、Flash、Dreamweaver、ASP、PHP、JSP...中激发了兴趣,然后越走越远....</p> 24 <p><img src="/static/images/01.jpg"></p> 25 <p>“冥冥中该来则来,无处可逃”。 </p> 26 </ul> 27 28 </div> 29 </div> 30 <div class="blank"></div> 31 </div> 32 <!-- container代码 结束 --> 33 {% endblock %}
接着完成路由指出
from django.conf.urls import include, url from django.contrib import admin from Article.views import * urlpatterns = [ url(r‘^admin/‘, include(admin.site.urls)), url(r‘^ckeditor/‘, include(‘ckeditor_uploader.urls‘)), url(r‘^ckeditor/‘, include(‘ckeditor_uploader.urls‘)), url(r‘^index/‘, index), url(r‘^myArticle/‘, myArticle), url(r‘^myPicture/‘, myPicture), url(r‘^aboutMe/‘, aboutMe), url(r‘^connectMe/‘, connectMe), ]
最后通过base页完成前端路由的修整,这样,我们的网站就可以点进选择了。
<!--……--> <ul class="menu"> <li><a href="/index/">网站首页</a></li> <ul> <li><a href="/aboutMe/">个人简介</a></li> <li><a href="/myPicture/">个人相册</a></li> </ul> </li> <li><a href="/myArticle/">我的博客</a> <ul> <li><a href="/myArticle/">个人博客</a></li> <li><a href="/myArticle/">技术博客</a></li> </ul> </li> <li><a href="/myPicture/">我的照片</a></li> <li><a href="/aboutMe/">关于我</a> <li><a href="/aboutMe/">给我留言</a> </li> </ul> </div> </nav> <SCRIPT type=text/javascript> <!--……-->
这样,我们就完成了最基本的前端效果。然后就可以在后台添加数据,进行数据的基本调用了
原文地址:https://www.cnblogs.com/bianjinhui/p/9831660.html