前言
Django + Boostrap
现在是运维开发的必备技能,因为他俩是运维可视化的关键技术,而本文就是简单说一下整个Django的数据库---后台---前端
的工作原理。其实所谓Django开发,就是熟悉了 Django的规则之后,按照它的规则去填空,填你自己想要展现的东西。
环境:django 2.0
+ python 3.6
+ pycharm 2018
django建立一个app之后就会有models.py
、views.py
、admin.py
这几个文件,他们三个分别的用途如下:
models.py
主要是用来设置数据在数据库的存储格式(比如默认值,字段类型和字段长度等等);admin.py
是用来设置在/admin/后台里面的显示样式;views.py
是用来设置在前台网页里的显示样式;urls.py
是用来编辑域名规则;
上面4个文件里,重中之重的就是views.py
,说它是整个django的灵魂都不为过!所以要是掌握了它,基本就明白了大半个django了。
举个例子
假设有一个models.py
,内容如下:
1
2
3
4
5
6
7from django.db import models
from django.contrib.auth.models import User
class BlogType(models.Model):
type_name = models.CharField(max_length=15) #规定type_name是一个最大为15字节的charfield
def __str__(self):
return '<BlogType:%s>' % self.type_name
然后随便加入一些内容,如图:
而在views.py
里,要求在前端网页里如此的显示:
1
2
3
4
5
6
7from django.shortcuts import render_to_response,get_object_or_404
from .models import BlogType #这里引用了models.py里的那个class
def blog_list(request):
context = {}
context['blog_types'] = BlogType.objects.all()
return render_to_response('pageblog/blog_list.html',context)
在views.py
里规定,如果有访问域名是/blog_list/
的网页,就返回pageblog/blog_list.html
这个页面,而这个blog_list.html
只是一个框架,里面的内容是context
。context
本身是一个字典,里面的key对应的value是用ojbects这个函数获得的,objects.all()
就是获取全部的意思。用来填充blog_list.html
的context里面有blog_types
这个key。
那么现在就可以在blog_list.html
里使用blog_types
这个key了,如下:
1
2
3
4<!-- 前面略 -->
<h4>博客分类</h4>
<h3> {{ blog_types }} </h3> <!-- html文件要用views.py里的变量要加上{{}} -->
<!-- 后面略 -->
这样的效果如下:
返回的是QuerySet
类型,QuerySet
是Django的查询集,可以通过QuerySet
条件查询得到对应模型的对象集合。由此看出blog_types
已经成功的引入到了blog_list.html
里。
至于拆成每一个“博客类型”就很简单了,html部分如下:
1
2
3
4
5
6
7
8
9
10<h4>博客分类</h4>
<!-- ul是无项目的标签 -->
<ul>
{% for blog_type in blog_types%} #开始一个for循环
<li><a href="{% url 'blogs_with_type' blog_type.pk %}">{{ blog_type.type_name }} </a></li> #对每一个类型加上一个a链接
{% empty %} #如果为空就说“暂无分类”
<!-- li是具体的项目 -->
<li> 暂无分类 </li>
{% endfor %}
</ul>
再说urls.py
上面说过了,urls.py
是配置域名路由规则的。它的格式比较简单,就是path('域名',views.py里的函数,name='自定义名称')
。比如下面这个urls.py
:
1
2
3
4
5
6
7
8
9from django.contrib import admin
from django.urls import include,path
from article.views import blog_list #article是django项目里自己创建的一个app
urlpatterns = [
path('',blog_list,name='home'), #这里的name可写可不写,如果写的话,在href跳转的时候就可以直接用
path('admin/', admin.site.urls),
path('blog/',include('article.urls')), #引用的的include方法用在这里
]
上面这个是总的路由文件,当然可以把所有的app的路由都写到里面去,也可以在各自的app下写各自的路由,这样方便管理。比如我就在article
这个app文件夹下面又单独了一个urls.py
,这里面所有的域名就会自动添加blog/
这个路径,而整个urls.py
内容如下:
1
2
3
4
5
6
7from django.urls import path
from . import views
urlpatterns = [
path('<int:blog_pk>',views.blog_detail,name='blog_detail'),
path('type/<int:blog_type_pk>',views.blogs_with_type,name='blogs_with_type'),
]
在上面的第一个path里,目的就是传入一个值blog_pk
,而这个blog_pk
就是在views.py
里的blog_detail
函数需要传入的参数,跟request
一样。上面也说过了,这个两个path都会自动在前面加上/blog/
路径。
views.py与前端
如何把数据库里的内容映射到前端页面呢?就是用views.py
里的render_to_response
,它是负责渲染的。render_to_response
的用法是后面要加上对应的html页面和要映射的内容,比如下面这个views.py
:
1
2
3
4
5
6
7from django.shortcuts import render_to_response,get_object_or_404
from .models import Blog #这里引用了models.py里面的类:Blog
def blog_detail(request,blog_pk): #每一次使用这个函数都要传入一个参数:blog_pk
context = {}
context['blog'] = get_object_or_404(Blog,pk=blog_pk) #通过get_object_or_404这个方法生成一个字典
return render_to_response('blog_detail.html',context) #这个blog_detail.html就是对应的前端页面
从上面可以看到,views.py
先引入了数据库文件models.py
里的Blog
这个class,然后设定一个空字典,将这个字典按照对应数据库默认的主键pk与浏览器输入的pk一一对应填满,最后就是按照blog_detail.html
为前端框架,里面赋予整个填满值的context字典。
而对应的前端页面blog_detail.html
如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>{{ blog.title }}</title> <!-- 这里的blog就是views.py里context['blog']里的blog -->
</head>
<body>
<div>
<a href="{% url 'home' %}"> <!-- 这里就是返回首页,home是在urls.py里设定的 -->
<h2>BACK TO HOMEPAGE</h2>
</a>
</div>
<h3>{{ blog.title }}</h3>
<p>作者:{{ blog.author }}</p>
<p>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}"> <!-- 就是将blog.blog_type.pk作为views.py里blog_detail函数的传入值 -->
{{ blog.blog_type }}
</a>
</p>
<p> {{ blog.blog_type.pk }}</p>
<p>发表时间:{{ blog.created_time|date:"Y-m-d H:i:s"}}</p> <!-- 这里将输出时间做了规范化 -->
<hr>
<p>{{ blog.content }}</p>
</body>
</html>