zoukankan      html  css  js  c++  java
  • Django博客开发数据建模与样式设定

    开发流程介绍

    之前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>
     <!--……-->

    这样,我们就完成了最基本的前端效果。然后就可以在后台添加数据,进行数据的基本调用了

  • 相关阅读:
    GIT非常见命令使用笔记
    视频封转类
    IOS ASIFormDataRequest使用简介(2/25)
    开发中常用的宏
    数据库使用fmdb
    毕业五年决定你的命运-----值得所有不甘平庸的人看看
    关于路径的使用,assi下载和
    关于图片处理的方法整理
    iOS开发之Objective-C与JavaScript的交互(转载)
    IOS UIWebView引用外部CSS样式(转载)
  • 原文地址:https://www.cnblogs.com/bianjinhui/p/9831660.html
Copyright © 2011-2022 走看看