一
1.1.环境搭建
(1)准备
pip install django==1.11.8
(2)创建项目和app:website和blog
D:\学习历程\django学习\搭建个人博客>django-admin startproject website
D:\学习历程\django学习\搭建个人博客\website>python manage.py startapp blog
(3)设置中文和时区
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
(4)运行项目
python manage.py runserver #浏览器访问http://127.0.0.1:8000/
1.2.模型设计
(1)blog/models.py
1 from django.db import models 2 from django.contrib.auth.models import User 3 # Create your models here. 4 5 class Category(models.Model): 6 name=models.CharField('分类',max_length=128) 7 8 def __str__(self): 9 return self.name 10 #重写meta模块,修改在管理后台中的显示名称 11 class Meta: 12 verbose_name='博客分类' 13 verbose_name_plural=verbose_name 14 15 class Tag(models.Model): 16 name=models.CharField('标签',max_length=128) 17 18 def __str__(self): 19 return self.name 20 21 class Meta: 22 verbose_name='博客标签' 23 verbose_name_plural='博客标签' 24 25 class Entry(models.Model): 26 title=models.CharField('文章标题',max_length=128) 27 author=models.ForeignKey(User,verbose_name='作者',on_delete=models.CASCADE) #文章作者,这里关联的是django内置的User。一个文章只有一个作者,而一个作者有多篇文章。所以是多对一关系 28 img=models.ImageField(upload_to='blog_img',null=True,blank=True,verbose_name='博客配图') 29 body=models.TextField('正文') 30 abstract=models.TextField('摘要',max_length=256,null=True,blank=True) 31 visiting=models.PositiveIntegerField('访问量',default=0) 32 category=models.ManyToManyField(Category,verbose_name='博客分类') 33 tags=models.ManyToManyField(Tag,verbose_name='标签') 34 created_time=models.DateTimeField('创建时间',auto_now_add=True) #对象添加时的时间,修改对象不会改变时间 35 modifyed_time=models.DateTimeField('修改时间',auto_now=True) #对象添加或修改,对象也会一起更新 36 37 def __str__(self): 38 return self.title 39 40 class Meta: 41 ordering=['-created_time'] 42 verbose_name='博客正文' 43 verbose_name_plural=verbose_name
(2)blog/admin.py(注册模型)
from django.contrib import admin from .models import Category,Tag,Entry # Register your models here. class EntryAdmin(admin.ModelAdmin): list_display = ['title','author','visiting','created_time','modifyed_time'] admin.site.register(Category) admin.site.register(Tag) admin.site.register(EntryAdmin)
(3)设置为MySQL
#__init__.py import pymysql pymysql.install_as_MySQLdb() #settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'my_blog' , #数据库名 'USER':'root', #用户名 'PASSWORD':'root', #密码 'HOST':'localhost', #IP 'PORT':'3306' #端口 } }
(4)生成迁移文件和执行迁移
python manage.py makemigrations
python manage.py migrate
#可能那个pillow有问题。如果遇到,请卸载重装pillow,还有迁移之前要激活应用,在settings.py。
(5)创建超级管理员
python manage.py createsuperuser
1.3.url及视图设计
(1)website/urls.py
from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^blog/',include('blog.urls')), ]
(2)blog/urls.py
from django.conf.urls import url from . import views app='blog' urlpatterns=[ url(r'^$',views.index,name='blog_index'), url(r'^(?P<blog_id>[0-9]+)',views.detail,name='blog_detail'), ]
(3)blog/views.py
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def index(request): return render(request,'blog/index.html',locals()) def detail(request): return render(request,'blog/detail.html',locals())
(4)templates/index.html
{% extends 'blog/base.html' %} {% block title %}博客首页{% endblock %} {% block content %} 博客首页 <div style="height: 440px; " ></div> {% endblock %}
(5)templates/detail.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>博客详情页</title> </head> <body> <h1>{{ blog_id }}的详情</h1> </body> </html>
1.4.前端页面设计
(1)Bootstrap 下载放到一定位置
settings.py设置
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static'), ]
(2)blog/base.html
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.css' %}" rel="stylesheet"> <link href="{% static 'blog/css/blog_nav.css' %}" rel="stylesheet"> {% block css %}{% endblock %} </head> <body> <nav class="navbar navbar-fixed-top"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#my-nav" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">王者小喵喵</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="my-nav"> <ul class="nav navbar-nav"> <li class="active"><a href="/blog/">博客</a></li> <li ><a href="#">学习资源</a></li> <li ><a href="#">联系我</a></li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">搜索</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">登录</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> {% block content %}{% endblock %} <footer> <div class="footer" role="navigation"> <div class="container"> <div class="navbar-text"> <ul class="footer-text"> <li><a href="#">主页</a></li> <li><a href="#">联系我们</a></li> <li><a href="#">关于博主</a></li> <li><a href="#">文档支持</a></li> <li><a href="/blog/">博客首页</a></li> </ul> <p>Copyright © 2018 王者小喵喵 </p> </div> </div> </div> </footer> <script src="{% static 'jquery-3.3.1.js' %}"></script> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.js' %}"></script> {% block script %}{% endblock %} </body> </html>
(3)blog/static/blog/css/blog_nav.css
body { margin-top: 30px; font-weight: 400; /* Required padding for .navbar-fixed-top. Change if height of navigation changes. */ padding-top: 70px; } /* Navbar and footer (global) styling */ .navbar-fixed-top .nav { padding: 15px 0; } .navbar { color: black; border-width: thin; -webkit-transition: .2s; background-color: white; border-bottom: 1px solid #e0e0e0; background-color: white; } .navbar a { color: black; } .navbar-fixed-top .navbar-brand { padding: 0 15px; } .navbar-header .icon-bar { background-color: black; } .navbar-nav > li > .navbar-active { color: #E46E2E; } .navbar-scroll { background-color: white; animation-duration: 2s; animation-name: smooth; -moz-box-shadow: 1px 1px 1px #999; -webkit-box-shadow: 1px 1px 1px #999; box-shadow: 1px 1px 1px #999; } .jupytercon-nav > li > .black-tab { color: black; } .navbar-logo { height: 45px; } .nav > li > a { font-size: 20px; padding: 12px 16px 10px; } .nav > li > a:hover { background-color: transparent; color: #E46E2E; -webkit-transition: .2s; } .nav > li > a:focus { background-color: white; } .nav > li > a:active { background-color: #F8F8F8; } .nav > li > a:visited { background-color: #F8F8F8; } .tab:hover { background-color: transparent; color: #E46E2E; } .footer { background-color: #979797; } .footer p { color: white; padding-top: 10px; } .footer li { color: white; display: inline-block; text-decoration: none; } .footer a { color: white; text-decoration: none; } .footer li::after { content:" |"; } .footer li:last-of-type::after { content:""; } .footer-text { font-size: 16px; margin-left: 0; padding-left: 0; } .navbar-brand { float: left; height: 50px; padding: 15px 15px; font-size: 20px; line-height: 20px; margin-top: 27px; } nav .navbar-form{ padding: 10px; }
效果:
目录结构: