初始化
新建项目
#pycharm手动创建django项目或如下
$ django-admin.py startproject website
#创建Django app
$ python manage.py startapp blog
更改数据库配置(sqlite->mysql)
#/website/setting.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'blog', #数据库名字
'USER': 'root', #账号
'PASSWORD': 'tony', #密码
'HOST': '127.0.0.1', #IP
'PORT': '3306', #端口
}
}
更改数据库配置还需初始化
#/website/__init__.py
import pymysql
pymysql.install_as_MySQLdb()
#下面的只是调试
db = pymysql.connect("localhost", 'root', 'tony', 'blog')
cursor = db.cursor()
cursor.execute("select version()") #执行sql语句调试一波
data = cursor.fetchone()
print(data)
db.close()
模型设计
一个model也是一个数据库的映射
#/blog/models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField('分类',max_length=128)
def __str__(self):
return self.name
class Meta:
verbose_name = '博客分类'
verbose_name_plural = verbose_name
class Tag(models.Model):
name = models.CharField('标签', max_length=128)
def __str__(self):
return self.name
class Meta:
verbose_name = '博客标签'
verbose_name_plural = verbose_name
class Entry(models.Model):
title = models.CharField('文章标题',max_length=128)
author = models.ForeignKey(User,verbose_name='作者',on_delete=models.CASCADE)
img = models.ImageField(upload_to='blog_img',null=True,blank=True,verbose_name='博客配图')
body = models.TextField('正文',)
abstract = models.TextField('摘要',max_length=256,null=True,blank=True)
visiting = models.PositiveIntegerField('访问量',default=0)
category = models.ManyToManyField('Category',verbose_name='博客分类')
tags = models.ManyToManyField('Tag',verbose_name='标签')
created_time = models.DateTimeField('创建时间',auto_now_add=True)
modifyed_time = models.DateTimeField('修改时间',auto_now=True)
def __str__(self):
return self.title
class Meta:
ordering = ['-created_time']
verbose_name = '博客正文'
verbose_name_plural = verbose_name
admin:后台管理界面, 添加删除网站的内容
#/blog/admin.py
from django.contrib import admin
from . import models
class EntryAdmin(admin.ModelAdmin):
list_display = ['title','author','visiting','created_time','modifyed_time']
admin.site.register(models.Category)
admin.site.register(models.Tag)
admin.site.register(models.Entry,EntryAdmin)
创建超级用户
$ python manage.py createsuperuser
此时如果出现No such Table ‘auth_user’,说明没有初始化(创建)默认数据库表
创建默认库
$ python manage.py migrate
如果已经运行过上面命令,就$ python manage.py makemigrations
url、views
#/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') ),
]
#/blog/urls.py
from django.conf.urls import url
from . import views
app_name = 'blog'
urlpatterns = [
url(r'^$', views.index,name='blog_index'),
url(r'^(?P<blog_id>[0-9]+)', views.detail,name='blog_detail'),
]
#/blog/views.py
from django.shortcuts import render
def index(request):
return render(request,'blog/index.html',locals())
def detail(request,blog_id):
return render(request,'blog/detail.html',locals())
基本前端
bootstrap和js都放进/static/
#/website/setting.py 添加静态文件路径
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
]
#/blog/templates/blog/detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博客详情</title>
</head>
<body>
<h1>博客{{ blog_id }}的详情</h1>
</body>
</html>
#/blog/base.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
<link href="{% static 'bootstrap/css/bootstrap.min.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="#">hhh</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 hh </p>
</div>
</div>
</div>
</footer>
<script src="{% static 'jquery-3.3.1.min.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
{% block script %}{% endblock %}
</body>
</html>
#/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;
}
#/blog/index.html
{% extends 'blog/base.html' %}
{% block title %}博客首页{% endblock %}
{% block content %}
博客首页
<div style="height: 440px; " ></div>
{% endblock %}
最终目录如下:
前端设计
#/website/setting.py
....
MEDIA_ROOT = os.path.join(BASE_DIR,'media').replace("//","/")
MEDIA_URL = '/media/'
添加图片的url
#/website/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/',include('blog.urls') ),
] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT ) #添加图片的url
添加两个方法
#/blog/models.py
class Entry(models.Model):
...
def get_absolute_url(self):
#获取当前博客详情页的url
return reverse("blog:blog_detail",kwargs={"blog_id":self.id}) #app名字,详情页url的别名,参数是当前博客的id
def increase_visiting(self):
#访问量加1
self.visiting += 1
self.save(update_fields=['visiting']) #只保存某个字段
#/blog/views.py
from django.shortcuts import render
from . import models
def index(request):
entries = models.Entry.objects.all()
return render(request,'blog/index.html',locals())
def detail(request,blog_id):
entry = models.Entry.objects.get(id=blog_id)
entry.increase_visiting()
return render(request,'blog/detail.html',locals())
#index.html
{% extends 'blog/base.html' %}
{% block title %}博客首页{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-9">
{% for entry in entries %}
<h2><a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a></h2> <br>
{% if entry.img %}
<img src="{{ entry.img.url }}" width="60%" height="270px"/>
{% endif %}
{% if entry.abstract %}
<p>{{ entry.abstract }}</p>
{% else %}
<p>{{ entry.body|truncatechars:180 }}</p>
{% endif %}
<p>
<span>作者:{{ entry.author }}</span>
<span> 发布时间:{{ entry.created_time }}</span>
<span> 阅读数:{{ entry.visiting }}</span>
</p>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
#detail.html
{% extends 'blog/base.html' %}
{% block title %}博客详情页{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-9">
<h1>{{ entry.title }}</h1>
<p>
<strong>{{ entry.author }}</strong>
{{ entry.created_time|date:'Y年m月d日' }}
分类:
{% for category in entry.category.all %}
<a href="#">{{ category.name }}</a>
{% endfor %}
标签:
{% for tag in entry.tags.all %}
<a href="#">{{ tag.name }}</a>
{% endfor %}
浏览量:
{{ entry.visiting }}
{% if entry.img %}
<img src="{{ entry.img.url }}" width="60%" height="270px"/>
{% endif %}
<hr />
<p>
{{ entry.body }}
</p>
</p>
</div>
</div>
</div>
{% endblock %}
Markdown排版、语法高亮和生成目录
pip install markdown
pip install pygments
pygmentize -S default -f html -a .codehilite > code.css #可生成code.css文件,也就是语法高亮的样式,然后把文件放到static里
配置md
# /blog/views.py
import markdown
from django.shortcuts import render
from . import models
def index(request):
entries = models.Entry.objects.all()
return render(request,'blog/index.html',locals())
def detail(request,blog_id):
entry = models.Entry.objects.get(id=blog_id)
md = markdown.Markdown(extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
'markdown.extensions.toc',
])
entry.body = md.convert(entry.body)
entry.toc = md.toc
entry.increase_visiting()
return render(request, 'blog/detail.html', locals())
导入css
#base.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock %}</title>
<link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
<link href="{% static 'blog/css/blog_nav.css' %}" rel="stylesheet">
<link rel="stylesheet" href="{% static 'blog/css/code.css' %}"> #这里引入css
</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="#">hhh</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 hh </p>
</div>
</div>
</div>
</footer>
<script src="{% static 'jquery-3.3.1.min.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
{% block script %}{% endblock %}
</body>
</html>
#detail.html
{% extends 'blog/base.html' %}
{% load staticfiles %}
{% block title %}博客详情页{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-9">
<h1>{{ entry.title }}</h1>
<p>
<strong>{{ entry.author }}</strong>
{{ entry.created_time|date:'Y年m月d日' }}
分类:
{% for category in entry.category.all %}
<a href="#">{{ category.name }}</a>
{% endfor %}
标签:
{% for tag in entry.tags.all %}
<a href="#">{{ tag.name }}</a>
{% endfor %}
浏览量:
{{ entry.visiting }}
{% if entry.img %}
<img src="{{ entry.img.url }}" width="10%" height="10%"/>
{% endif %}
<hr />
<p>
{{ entry.toc|safe }} #给加上safe过滤器,表示不需要转义,直接显示原始内容
{{ entry.body|safe }} #一样
</p>
</p>
</div>
</div>
</div>
{% endblock %}
然后在blog查看效果
暂时先搁置,发现还有挺多没学到的东西。。
参考:
http://wiki.jikexueyuan.com/project/django-set-up-blog/models.html
https://www.cnblogs.com/derek1184405959/p/9060981.html