声明:本渣渣部分代码参考自TendCode其实有不少代码是不须要本身一行行码出来,生产力是第一位。只有研究型人才须要生产代码,做为一名渣渣拿来用是最高效的作法。程序员都有一个开源的精神,码出来的代码自己是但愿更多的人用到,应用到生产中。
参考编写博客的 Model 与首页面
整合资源也应该是一个码农的必备能力,在实际生产中能够更高效的工做html
windows10
python==3.6.6
django==1.11.1
首先本渣渣想对django项目结构作一下梳理,若是有的读者对django不太熟悉,可能阅读有障碍。
对django基础作一下简单了解。前端
推荐阅读:vue
Django1.10 中文文档python
大牛翻译的django基础部分mysql
简单了解通用视图git
开始 Django 开发以前,须要掌握如下知识:
• 建立 Django 工程,了解 Django 默认的工程目录结构
• 建立 Django APP
• 理解 Django 的MTV 模式,学会编写 Model、View、Template
• Django 如何处理静态文件,即各类 CSS,JS,以及图片文件等程序员
推荐阅读:
我的博客-建立项目
Django中MVC与MVT设计模式github
一、 用户经过浏览器输入相应的 URL 发起 HTTP 请求(通常是 GET/POST)
用户在网站前台作的每次操做都是一次HTTP请求的触发,经过触发的URL,和后台进行交互
2:Django后台接收到请求,检测 urls.py 文件,找到和用户请求的URL 相匹配的项,而后调用该 URL 对应的视图函数(view),在视图内进行逻辑呈现,而后渲染数据到模板展现给用户。redis
推荐阅读:sql
视图函数被调用后,可能会访问数据库(Model)去查询用户想要请求的数据,并加载模板文件(Template),渲染完数据后打包成 HttpResponse 返回给浏览器(Http协议)
从流程能够看出,开发者须要作的事情以下:
• 编写相应的 url
• 编写数据库(Model)
• 编写处理 Http 请求的视图函数(View)
• 编写须要渲染数据的模板(Template)
下面遵循这样的开发流程继续进行咱们我的博客的开发:
虽然博客站点的django项目已经烂大街了,可是不少人还没意识到我的博客的价值,有时间咱们能够谈谈这个问题。
初版选择使用Django通用视图开发,后续升级先后端分离开发(正在学习中)
推荐阅读:
在接触到django到如今看到的教程大都没有采用django的通用视图,可是为了更好的认识django,在这里本渣渣,想尝试尽可能在开发博客主体时使用通用视图
一、 目前在看到的django教程中大部分都未使用通用视图,顶可能是继承通用类。这样你就没办法真正了解django框架,django独特之处就在于构建Web应用程序的经常使用功能已经在框架内,而不是单独的库。通用视图是Django为解决建站过程当中的常见的呈现模式而创建的
通用视图使用原则
代码越少越好
永远不要重复代码
view应当只呈现逻辑, 不该包含业务逻辑
保持view逻辑清晰简单
二、 锻炼快速高效开发一类网站的能力
了解了通用视图你能够快速开发一类网站好比博客、论坛都有类似的需求
三、 组合方便
这里本渣渣的作法是扒取崔庆才我的博客前端源码,而后经过django实现网站后端开发,使用django 通用视图,能够缩短开发周期,并且可以具有使用django快速模仿一个网站的能力
下面不废话开干
按流程来,规范的流程少出错,严谨应该是一个码农的素养
目前项目文件结构
把抓取崔庆才我的博客网站前端源码一文中抓取的崔庆才博客前端源码放入我的博客-建立项目一文中建立的项目中
https://www.jianshu.com/p/246...
设置blog/settings.py
添加 apps 目录
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
添加app
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'storm', ]
添加模板
ROOT_URLCONF = 'blog.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 设置视图 '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', ], }, }, ]
链接数据库,首先要在本地数据库建立名为blog的数据库
这里须要用到数据库链接包,
请参考安装python包到虚拟环境安装包
Name: mysqlclient
Version: 1.4.2.post1
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': 'localhost', 'PORT': '3306', 'USER': 'root', 'PASSWORD': 'root', 'NAME': 'blog', # 若是建立的数据库是uft-8编码,映射数据库时出现警告,添加此行解决问题 'OPTIONS': { 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", 'charset': 'utf8mb4', }, } }
配置静态文件路径
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ]
针对blog开发大致有这几个通用的models类
文章、幻灯片、文章标签、文章分类、友情连接
这里为了后期可以更好的给本站作SEO优化,这里添加了一个,文章关键词,死链
文章、幻灯片、文章标签、文章分类、友情连接、关键词、死链
因而可知,设计数据库结构就是编写 models,数据库中每个实体对应的表在 django 中对用着 models.py 中的一个类,类的属性对应着数据库表的属性列。
# 文章关键词,用来做为SEO中keywords class Keyword(models.Model): name = models.CharField('文章关键词', max_length=20) class Meta: verbose_name = '关键词' verbose_name_plural = verbose_name ordering = ['name'] def __str__(self): return self.name # 文章标签 class Tag(models.Model): name = models.CharField('文章标签', max_length=20) slug = models.SlugField(unique=True) description = models.TextField('描述', max_length=240, default=settings.SITE_DESCRIPTION, help_text='用来做为SEO中description,长度参考SEO标准') class Meta: verbose_name = '标签' verbose_name_plural = verbose_name ordering = ['id'] def __str__(self): return self.name def get_absolute_url(self): return reverse('blog:tag', kwargs={'slug': self.slug}) def get_article_list(self): '''返回当前标签下全部发表的文章列表''' return Article.objects.filter(tags=self) # 文章分类 class Category(models.Model): name = models.CharField('文章分类', max_length=20) slug = models.SlugField(unique=True) description = models.TextField('描述', max_length=240, default=settings.SITE_DESCRIPTION, help_text='用来做为SEO中description,长度参考SEO标准') class Meta: verbose_name = '分类' verbose_name_plural = verbose_name ordering = ['name'] def __str__(self): return self.name def get_absolute_url(self): return reverse('blog:category', kwargs={'slug': self.slug}) def get_article_list(self): return Article.objects.filter(category=self) # 文章 class Article(models.Model): # 文章缩略图 IMG_LINK = '/static/img/summary.png' author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='做者') # 文章标题,CharField 表示对应数据库中数据表的列的数据类型,'标题'是一个位置参数 #(verbose_name),主要用于 django 的后台系统。max_length 表示能存储的字符串 # 的最大长度 title = models.CharField(max_length=150, verbose_name='文章标题') # 这里填的内容有助于后期SEO优化 summary = models.TextField('文章摘要', max_length=230, default='文章摘要等同于网页description内容,请务必填写...') # 文章正文,TextField 用来存储大文本字符 body = models.TextField(verbose_name='文章内容') # 文章缩略图地址 img_link = models.CharField('图片地址', default=IMG_LINK, max_length=255) # 文章建立时间,DateTimeField用于存储时间,设定auto_now_add参数为真,则在文章被建立时会自动添加建立时间 create_date = models.DateTimeField(verbose_name='建立时间', auto_now_add=True) # 文章最后一次编辑时间,auto_now=True表示每次修改文章时自动添加修改的时间 update_date = models.DateTimeField(verbose_name='修改时间', auto_now=True) # 阅览量,PositiveIntegerField存储非负整数 # views = models.PositiveIntegerField('阅览量', default=0) views = models.IntegerField('阅览量', default=0) slug = models.SlugField(unique=True) # 文章的分类,ForeignKey即数据库中的外键。外键的定义是:若是数据库中某个表的列的值是另一个表的主键。外键定义了一个一对多的关系,这里即一篇文章对应一个分类,而一个分类下可能有多篇文章。详情参考django官方文档关于ForeinKey的说明,on_delete=models.SET_NULL表示删除某个分类(category)后该分类下全部的Article的外键设为null(空) category = models.ForeignKey(Category, verbose_name='文章分类',on_delete=models.SET_NULL) tags = models.ManyToManyField(Tag, verbose_name='标签') keywords = models.ManyToManyField(Keyword, verbose_name='文章关键词', help_text='文章关键词,用来做为SEO中keywords,最好使用长尾词,3-4个足够') def __str__(self): # 主要用于交互解释器显示表示该类的字符串 return self.title class Meta: verbose_name = '文章' verbose_name_plural = verbose_name ordering = ['-create_date'] # 幻灯片 class Carousel(models.Model): number = models.IntegerField('编号', help_text='编号决定图片播放的顺序,图片不要多于5张') title = models.CharField('标题', max_length=20, blank=True, null=True, help_text='标题能够为空') content = models.CharField('描述', max_length=80) img_url = models.CharField('图片地址', max_length=200) url = models.CharField('跳转连接', max_length=200, default='#', help_text='图片跳转的超连接,默认#表示不跳转') class Meta: verbose_name = '图片轮播' verbose_name_plural = verbose_name # 编号越小越靠前,添加的时间越晚越靠前 ordering = ['number', '-id'] def __str__(self): return self.content[:25] # 死链 class Silian(models.Model): badurl = models.CharField('死链地址', max_length=200, help_text='注意:地址是以http开头的完整连接格式') remark = models.CharField('死链说明', max_length=50, blank=True, null=True) add_date = models.DateTimeField('提交日期', auto_now_add=True) class Meta: verbose_name = '死链' verbose_name_plural = verbose_name ordering = ['-add_date'] def __str__(self): return self.badurl class FriendLink(models.Model): name = models.CharField('网站名称', max_length=50) description = models.CharField('网站描述', max_length=100, blank=True) link = models.URLField('友链地址', help_text='请填写http或https开头的完整形式地址') logo = models.URLField('网站LOGO', help_text='请填写http或https开头的完整形式地址', blank=True) create_date = models.DateTimeField('建立时间', auto_now_add=True) is_active = models.BooleanField('是否有效', default=True) is_show = models.BooleanField('是否首页展现', default=False) class Meta: verbose_name = '友情连接' verbose_name_plural = verbose_name ordering = ['create_date'] def __str__(self): return self.name def get_home_url(self): '''提取友链的主页''' u = re.findall(r'(http|https://.*?)/.*?', self.link) home_url = u[0] if u else self.link return home_url def active_to_false(self): self.is_active = False self.save(update_fields=['is_active']) def show_to_false(self): self.is_show = True self.save(update_fields=['is_show'])
model 定义完毕后,运行如下命令便可生成相应的数据库表:
python manage.py makemigrations
python manage.py migrate
针对models分别给出如下参考资料供学习:
Models:
官方文档
Django1.10 中文文档
大牛翻译
推荐学习:
自强学堂
Django的ORM映射机制与数据库实战
数据库模型(Models)对象映射表ORM
ForeinKey(一对多)、ManyToMany(多对多)、OneToOne(一对一):
官方文档
Django的ORM映射机制与数据库实战
上面已经介绍了 django 应用的工做流程,数据库创建完毕后须要编写视图函数(view)来处理 Http 请求。一样先来看 django 的 view 代码是如何写的,这里数据库内没有文章先不作文章展现逻辑编写,待后续一一进行,这里只写一个视图让首页能够被访问。
视图代码
from django.views import generic from django.conf import settings from .models import Article, Tag, Category, Timeline, Silian # Create your views here. class IndexView(generic.ListView): """ 首页视图,继承自ListVIew,用于展现从数据库中获取的文章列表 """ # 获取数据库中的文章列表 model = Article # template_name属性用于指定使用哪一个模板进行渲染 template_name = 'index.html' # context_object_name属性用于给上下文变量取名(在模板中使用该名字) context_object_name = 'articles'
blog/urls.py
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), # allauth url(r'^accounts/', include('allauth.urls')), # storm url('', include('storm.urls', namespace='blog')), # blog ]
apps/storm/urls.py
# --------------------------- __author__ = 'stormsha' __date__ = '2019/2/20 23:27' # --------------------------- from django.conf.urls import url # from .views import goview from .views import IndexView urlpatterns = [ url(r'^$', IndexView.as_view(), name='index'), # 主页,天然排序 ]
如今首页流程基本走通之,差视图内的逻辑、和数据渲染的问题了,静待后续。
本渣渣也是在繁忙的工做之余,抽出点时间想本身搞一下博客,可是不想草草了事,想从这个项目中实践以下知识
抓取网站前端页面源码、Django通用视图、django rest framework、vue.js、redis数据缓存、docker容器部署、git、SEO技术
钱途:想法——实现——部署——运营——维护——盈利
有什么问题欢迎留言,或者关注微信公众号「stormsha」进行深度技术、思惟碰撞交流。