首页 > 技术文章 > Django 框架概况

iyouyue 2018-01-22 20:05 原文

Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式:

    M 代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务:如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。

    T 代表模板(Template),即表现层。 该层处理与表现相关的决定:如何在页面或其他类型文档中进行显示。

    V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。你可以把它看作模型与模板之间的桥梁。

一 路由系统

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;
你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码

urlpatterns = [
    url(正则表达式, views视图函数,参数,别名),
]
 
参数说明:
 
    一个正则表达式字符串
    一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    一个可选的要传递给视图函数的默认参数(字典形式)
    一个可选的name参数

对应方式

1.单一对应:url(r'^index$', views.index)
2.基于正则的路由:
url(r'^index/(\d{4})$',views.index)
url(r'^index/(\d{4})/(\d{2})',views.index) # 分组
url(r'^index/(?P<year>\d{4})/(?P<month>\d{2})',views.index)  # 分组+命名
3.添加额外的参数:
url(r'^manage/(?P<name>\w*)', views.manage,{'id':333})
4.为路由映射设置名称和使用:
url(r'^home', views.home, name='h1'),
url(r'^index/(\d*)', views.index, name='h2'),
	用法:
	- 模板中使用生成URL     {% url 'h2' 2012 %}
	- 函数中使用生成URL     reverse('h2', args=(2012,))      路径:django.urls.reverse
	- Model中使用获取URL    自定义get_absolute_url() 方法
5.根据app对路由规则进行分发:
url(r'^app01/',include("app01.urls"))
url(r'^app02/',include("app02.urls"))
  
#没有匹配成功,返回默认页面
url(r'^',include("views.default")) 
6.命名URL和反向解析:
例:
url(r'^home', views.home, name='home'),  # 给我的url匹配模式起名为 home
url(r'^index/(\d*)', views.index, name='index'),  # 给我的url匹配模式起名为index

在模板里引用:
{% url 'home' %}

在views函数中引用:
from django.urls import reverse
reverse("index", args=("2018", ))

7.命名空间:

二 模型M(Model)

在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。
通常,一个模型(model)映射到一个数据库表,

基本情况:
	- 每个模型都是一个Python类,它是django.db.models.Model的子类。
	- 模型的每个属性都代表一个数据库字段。
	- 综上所述,Django为您提供了一个自动生成的数据库访问API

ORM增删改查

# 增
models.Tb1.objects.create(c1='xx', c2='oo')   # 增加一条数据,可以接受字典类型数据 **kwargs
obj = models.Tb1(c1='xx', c2='oo')
obj.save()


# 查
models.Tb1.objects.get(id=123)  # 获取单条数据,不存在则报错(不建议)
models.Tb1.objects.all()  # 获取全部
models.Tb1.objects.filter(name='seven')  # 获取指定条件的数据
models.Tb1.objects.exclude(name='seven')  # 去除指定条件的数据


# 删
# models.Tb1.objects.filter(name='seven').delete()  # 删除指定条件的数据


# 改
models.Tb1.objects.filter(name='seven').update(gender='0')   # 将指定条件的数据更新,均支持 **kwargs
obj = models.Tb1.objects.get(id=1)
obj.c1 = '111'
obj.save()   # 修改单条数据

三 模板T(Template)

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),
然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

{{ }}和 {% %}: 变量相关的用{{ }},逻辑相关的用{% %}。

3.1 模板语言

1 变量:

{{ 变量名 }}
变量名由字母数字和下划线组成。
点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。

2 Filters过滤器:

语法: {{ value|filter_name:参数 }}

default
{{ value:default: "nothing"}}
如果value值没传的话就显示nothing

length
{{ value|length }}
返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:
{{ value|filesizeformat }}
如果 value 是 123456789,输出将会是 117.7 MB。

slice
{{value|slice:"2:-1"}}

date格式化
{{ value|date:"Y-m-d H:i:s"}}

safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。
比如:
value = "<a href='#'>点我</a>"
{{ value|safe}}

3 标签:

- for循环:
<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>
forloop.counter	当前循环的索引值(从1开始)
forloop.counter0	当前循环的索引值(从0开始)
forloop.first 	当前循环是不是第一次循环(布尔值)
forloop.last	当前循环是不是最后一次循环(布尔值)
- for ... empty
- if,elif 和else
- if ... else
- with 定义一个中间变量

4 母版:

继承模板:{% extends "xxxx.html" %}

重写模板:
在母版和子版式中使用同样的:
{% block 取个名字 %}
    (每个子版专属的代码)
{% endbloack %}

导入html代码:
{% include "xxx.html" %}

四 视图V(View)

一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。
响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。
无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。

4.1 FBV和CBV

CBV示例:

# urls.py中
url(r'^login.html$', views.Login.as_view()),

# views.py中
from django.views import View
class Login(View):
     
    def dispatch(self, request, *args, **kwargs):
        print('before')
        obj = super(Login,self).dispatch(request, *args, **kwargs)
        print('after')
        return obj
 
    def get(self,request):
        
        return render(request,'login.html')
 
    def post(self,request):
        print(request.POST.get('user'))
        return HttpResponse('Login.post')

4.2 HttpRequest对象(请求)

属性:

	request.method
	request.POST
	request.GET
	request.path
	request.FILES

	request.cookie
	request.session

方法:

	request.get_host()
	request.get_full_path()
	request.get_signed_cookie()
	request.is_ajax()

4.3 HttpResponse对象(响应)

使用:

1.传递字符串:
from django.http import HttpResponse
response = HttpResponse("Here's the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")
2.设置和删除响应头:
response = HttpResponse()
response['Content-Type'] = 'text/html; charset=UTF-8'
del response['Content-Type']

属性:

HttpResponse.content:响应内容
HttpResponse.charset:响应内容的编码
HttpResponse.status_code:响应的状态码

JsonResponse对象:

JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
from django.http import JsonResponse
response = JsonResponse({'foo': 'bar'})
print(response.content)
b'{"foo": "bar"}'
默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。
response = JsonResponse([1, 2, 3], safe=False)

Django shortcut functions:
1.render()

from django.shortcuts import render
def my_view(request):
    # 视图的代码写在这里
    return render(request, 'myapp/index.html', {'foo': 'bar'})
上面的代码等于:
from django.http import HttpResponse
from django.template import loader

def my_view(request):
    # 视图代码写在这里
    t = loader.get_template('myapp/index.html')
    c = {'foo': 'bar'}
    return HttpResponse(t.render(c, request))

2.redirect()

参数可以是:
	一个模型:将调用模型的get_absolute_url() 函数
	一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
	一个绝对的或相对的URL,将原封不动的作为重定向的位置。
	默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。
def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object, permanent=True)

推荐阅读