浅析django里models.py、views.py与网页之间的爱恨纠葛

前言

Django + Boostrap现在是运维开发的必备技能,因为他俩是运维可视化的关键技术,而本文就是简单说一下整个Django的数据库---后台---前端的工作原理。其实所谓Django开发,就是熟悉了 Django的规则之后,按照它的规则去填空,填你自己想要展现的东西。

环境:django 2.0 + python 3.6 + pycharm 2018

django建立一个app之后就会有models.pyviews.pyadmin.py这几个文件,他们三个分别的用途如下:

  1. models.py主要是用来设置数据在数据库的存储格式(比如默认值,字段类型和字段长度等等);
  2. admin.py是用来设置在/admin/后台里面的显示样式;
  3. views.py是用来设置在前台网页里的显示样式;
  4. urls.py是用来编辑域名规则;

上面4个文件里,重中之重的就是views.py,说它是整个django的灵魂都不为过!所以要是掌握了它,基本就明白了大半个django了。

举个例子

假设有一个models.py,内容如下:

1
2
3
4
5
6
7
from 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

然后随便加入一些内容,如图:
paradin

而在views.py里,要求在前端网页里如此的显示:

1
2
3
4
5
6
7
from 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只是一个框架,里面的内容是contextcontext本身是一个字典,里面的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里的变量要加上{{}} -->
<!-- 后面略 -->

这样的效果如下:
paradin

返回的是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
9
from 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
7
from 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
7
from 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>

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------