Django框架介绍

Django框架介绍

MVC、MTV模型介绍

MVC模型

将web应用分为模型M、视图V、控制器C三部分
模型:负责业务对象与数据库映射
视图:负责用户交互
控制器:接受用户的输入,调用模型和视图完成用户的请求

MTV模型

将web应用分为模型M、模板T、视图V三部分
模板:负责把页面展示给用户
除此之外,还有一个URL分发器,负载把一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template

Django就是MTV模型

Django下载与创建新项目

Django下载

pip3 install django

创建一个Django项目

djang-admin.py startproject mysites
创建一个名为mysites的项目

创建一个Django应用

python manage.py startapp blog
创建一个名为blog的应用
注意:必须在项目下manage.py文件下面创建

启动Django项目

python manage.py runserver 8080
启动该项目,并且指定端口号8080
注意:不指定则默认127.0.0.1:8000

启动成功时,大致显示以下

Performing system checks...

System check identified no issues (0 silenced).

You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
August 12, 2018 - 15:26:57
Django version 2.0.1, using settings 'myproject1.settings'
Starting development server at http://127.0.0.1:8001/
Quit the server with CTRL-BREAK.

Django简单学习

Django目录分析

在项目目录mysites下有以下几个文件
settings.py: 配置文件,主要存储一些工作变量,数据库信息,调试标志
urls.py: url分发器,主要将传入的url映射到相应的视图函数
manage.py: Django项目里的工具,可以调用Django shell和数据库等

应用目录blog下文件分析
models: 主要用来存放调用数据库的程序
views: 主要用来存放视图函数

我们在urls中写url和相应的函数名,在views中实现该函数(注意返回render()对象),可以返回一个html页面。

在原目录下可以创建一个templates文件夹用来存放html文件。注意查看
找到setting-》找到TEMPLATES–》设置’DIRS’: [os.path.join(BASE_DIR, ‘templates’)]

render方法分析

该方法默认在views下面引入,自动读取HTML文件,返回bytes类型
render(request,"timer.html")不需要写任何路径,django自动找templatas文件夹

如何将视图函数中的参数传入html中?
render(request,"timer.html",{"date":timer})
将参数字典传给html,在html中使用参数<h4>当前时间{{date}}</h4>
{{}}是一种反向解析的符号

HttpRespone方法分析

HttpRespone响应对象,只需要传入字符串,响应体;不需要传入响应头
在views下引入
from django.shortcuts import HttpResponse
示例:

def hi(request):
    return HttpResponse("<h2>hi,you are bitch</h2>")

request类分析

我们每个视图函数都要有一个参数,即request;该类包含浏览器发过来的信息
在前端中form表单,method属性为提交方式,有GET和POST两种

方法名功能
request.method可以得到是"POST"还是“GET”
request.GET得到一个GET请求字典
request.POST得到一个POST请求字典

示例:
如果我们想要从POST请求中得到表单中用户名(假设input标签name为user)
request.POST.get("user")

静态文件配置

在页面中,我们想引入jquery,css,js文件时,我们需要这么做
先创建一个静态文件夹static,然后找到settings.py加入以下代码

STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"statics")
]

我们通过浏览器可以直接访问到里面的内容,url为/static/*
例如:<script src="/static/jquery-3.3.1.js">

路由控制

哪个URL由哪个视图函数来处理,服务器接受到客户端发过来的请求时,在urls.py文件夹中这样处理。

url组成
协议://ip:端口号/路径?get请求数据
注意:没有路径时,默认根目录

re_path

在Django1.0版本中,re_path相当于url函数.放在在urlpatterns列表里

导入方法
from django.urls import re_path

示例一:
re_path(r'^articles/2003/$', views.special_case_2003)
前面是正则表达式,后面是匹配的视图函数

示例二:
re_path(r"^([0-9]{4})/([0-9]{2})/",views.mydate)
当我们使用分组匹配时,视图函数必须要有相应分组的取去接受参数

def mydate(request,year,month):
    return HttpResponse("<h2>now time is</h2>"+year+"year,"+month+"month")

注意:

  • 路径不要添加前导斜杠^articles/2003/$不要写为^/articles/2003/$
  • 表达式前面最好加r,代表原始字符串,不用转义
  • 如果路径满足好几个表达式,取最先满足的表达式

有名分组
示例三:
re_path("^(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/",views.mydate)
给每个分组起名字后,视图函数将按照关键字传参,而不是位置传参.这里形参数必须为year,month,但是位置可以改变

path

在Django2.0中,默认使用path来处理url映射,放在在urlpatterns列表里
注意:在re_path中匹配的参数默认是字符串

导入方法
from django.urls import path

示例一:
urls中path("<int:year>/<int:month>/",views.mytime,name="y_m")
这里使用<>尖括号,int代表匹配任意多个数字,并转换为Int格式,year,month代表将匹配到的内容赋值给这个变量

默认转换器

转换器功能
str匹配除路径分隔符以外的非空字符串,默认
int匹配正整数包括0
slug匹配字母,数字以及斜杠,下划线组成的字符串
uuid匹配格式化uuid
path匹配任何非空字符串,包含路径分隔符

注意:没有转换器则匹配任何字符串,无需转换器前加前导斜杠

自定义转换器
当我们对匹配的内容有要求,且默认转换器不能满足我们的要求时,这时候我们就需要自定义转换器

首先定义一个类
包含一个regex类属性和to_python(self, value)方法和to_url(self, value)方法
to_python(self, value)方法:类属性regex所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中。
to_url(self, value)方法:和to_python相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
例如:

class MyMonth:
    regex = "[0-9]{2}"
    def to_python(self,value):
        return int(value)
    def to_url(self,value):
       return '%04d' % value

将其注册到urls配置中
导入模块
from django.urls import register_converter

注册转换器
register_converter(MyMonth,"mm")
将该转换器其别名为mm

使用转换器
path("<mm:month>/",views.mymonth),

分发

当我们一个项目有多个应用时,url控制器不应该直接处理传过来的地址,而是将其分发给指定的应用,让应用内的url控制器进行映射操作

导入方法
from django.urls import include

示例四:
将url开头为blog/的地址分发给blog里的url控制器(blog应用文件夹中必须创建一个urls.py文件)
re_path("^blog/",include("blog.urls"))

然后在blog的urls.py文件中添加相应的路由操作

from django.urls import re_path
from blog import views
urlpatterns = [
    re_path("hi/",views.hi)
]

注意:当url地址为http://127.0.0.1:8000/blog/hi/,项目url控制器得到的是blog/hi/,匹配到blog/后,将其分发给blog下的url控制器,该控制器得到的是hi/,即匹配到视图

反向解析

当我们在模板(html网页)或者python代码中需要url链接地址时,我们需要反向解析得到链接的地址

在使用反向解析前,我们需要给url起一个别名,以便在修改控制器地址时,不影响已经使用该地址的地方。

给一条re_path起别名
re_path("^info/",views.info,name="info"),

使用reverse在python代码中反向解析

导入模块
from django.urls import reverse

示例一:
urls中:re_path("^info/",views.info,name="info")
views中:

from django.urls import reverse
print(reverse("info"))

解析出地址为/info/只会解析出正则匹配的部分
比如地址后缀为/info/haha,解析出来还是为/info/

示例二:
urls中:re_path("^([0-9]{4})/([0-9]{2})",views.mytime,name="y_m")
views中:

def mytime(request,year,month):
    from django.urls import reverse
    return HttpResponse(reverse("y_m",args=(year,month)))

注意:当正则表达式分组匹配带有参数时,需要传入符合规范的参数,args的元组中

使用{% %}在html中反向解析

示例二:
html中:

<p>当前匹配到的年{{ year }} 月{{ month }}</p>
<p>反向解析{% url "y_m" year month %}</p>

第一个标签是{{变量}}的方式反向解析到year,month两个变量
在views视图函数中由render(request,"mytime.html",{"year":year,"month":month})这样传入的
第二个标签是{% “url的name” %},这个name是在url控制器中的一条re_path
re_path("^([0-9]{4})/([0-9]{2})",views.mytime,name="y_m")

名称空间

当我们使用include来分发url给不同应用时,我们可以设置一个名称空间,以便防止不同应用中名字重复

示例:
url中:re_path("^blog/",include("blog.urls",namespace="blog")),
views中:

urlpatterns = [
    re_path("hi/",views.hi,name="hi"),
]

在python中

def hi(request):
    return HttpResponse("<h2>hi,you are bitch,this is blog</h2>"+reverse("blog:hi"))

注意:
遇到这个错误时Specifying a namespace in include() without providing an app_name
app_name目录下的urls.py文件中urlpatterns前面加上app_name='[app_name]',其中app_name 为项目名称。
例如:app_name = "[blog]"

视图层

也就是views.py文件,主要是用于编写视图函数

from django.shortcuts import render,HttpResponse,reverse

def index(request):
    return render(request,"index.html")

index就是视图函数

request属性和函数

属性方法
request.GET存储get字典
request.POST存储post字典
request.method表示请求使用的HTTP方法,是POST还是GET
request.path表示请求的路径,不包括域名

访问网站:http://127.0.0.1:8080/abc?name=alex

函数方法
requset.path()请求路径(例如:返回/abc
request.get_full_path()请求路径包括?后面的选项(例如:返回 /abc?name=alex)

响应对象分析

对象属性
HttpResponse()传入一个字符串,直接将字符串发给浏览器
render()解析模板,将网页发给浏览器
redirect()传递要重定向的一个硬编码的URL
render()使用

将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应体。

def index(request):
    return render(request,"index.html")

传入request对象,模板对象,可选参数字典

redirect()使用

传递要重定向的一个硬编码的URL

def my_view(request):
    ...
    return redirect('http://example.com/')

默认返回临时重定向,参数permanent=True返回永久重定向
状态码301和302有什么区别?
301表示旧网页资源已被永久移除,搜索引擎抓取将旧网址交换为重定向之后的网址
302表示临时从旧地址A跳到地址B,搜索引擎会保存旧网址

模板层

通常将HTML文件存在templates文件夹中

变量

{{var_name}}将该语言写在HTML文件中,var_name映射的是python变量。在视图函数返回的render()中第三个参数传入的键值对,就是以python变量名为键,var_name为值。

如果变量名过多可以不用一个一个组成字典传入render()吗?
可以使用locals()函数,将函数内所有变量传入,但是在HTML中使用的名称和python变量名一致

点语法

语法功能示例
点+索引获取列表中的元素l1.1
点+键获取字典中的元素dic.name
点+属性获取对象属性date.year
点+方法获取对象方法(无参数)dic.name.upper

过滤器

{{obj|filter__name:param}}可以将传入的变量使用函数过滤掉,该函数最多可以再传入一个参数param

过滤器示例功能
default{value|default:"没有值"}如果变量为空时,设置默认值
length{l1|length}计算字符串或列表长度
data{value|date:"Y-m-d"}格式化时间
slice{value|slice:"1:-1"}列表切片操作
truncatechars{value|truncatechars:9}截断字符串
safe{value|safe}使变量中标签尖括号<>不必转义为&lt;&gt;

标签

第一种:{% tag %}
第二种{% tag %}{% endtag %}

for标签
使用for循环可以遍历变量
示例:

{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

可以使用{% for obj in list reversed %}反向完成循环

在for循环体中使用{% empty %}可以将变量为空或没有值的变量设置默认值

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

if标签
判断标签
示例:

{% if num > 100 or num < 0 %}
    <p>无效</p>
{% elif num > 80 and num < 100 %}
    <p>优秀</p>
{% else %}
    <p>凑活吧</p>
{% endif %}

with标签
给变量起别名
示例:

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

别名只能在中间使用

csrf_token标签
用于跨站请求伪造保护,通常写在用于post提交的form表单中
{% csrf_token %}

自定义标签和过滤器

前提:

  • 在setting.py文件下INSTALLED_APPS = []列表中添加应用名app
  • 该应用app下面有templates文件夹
  • 在templates文件夹下创建一个后缀名为py的文件例如my_tag_filter.py

文件中必须包含

from django import template
from django.utils.safestring import mark_safe
register = template.Library()   #register的名字是固定的,不可改变  
创建自定义过滤器
使用register.filter装饰器
@register.filter
def my_filter(x,y):
    return x+y

注意:自定义过滤器最多只能有两个参数,第一个参数为|前的参数,第二个参数为:后面的参数

HTML中使用示例

from templates.my_tag_filter import *
{{ num|my_filter:3 }}

假设num为4,这{{ num|my_filter 3}}结果为12
注意:使用自定义过滤器时,要导入相关文件

使用register.simple_tag装饰器
@simple_tag
def my_tag(x,y,z):
    return x+y+z

注意:使用自定义标签时,可以传入一个或多个参数,不受限制

HTML使用示例

from templates.my_tag_filter import *
{% my_tag 5 6 7 %}

{% my_tag 5 6 7 %}结果为18

自定义标签和自定义过滤器有什么不同???
  • 自定义标签使用{% tag %} 自定义过滤器使用{{ num|filter }}或者{% if num|my_filter:3 > 4 %}标签中
  • 自定义标签可以设置多个参数,自定义过滤器只可以设置两个参数
  • 自定义过滤器可以在if标签使用,自定义标签不行
    示例:
{% if num|my_filter:3 > 4 %}
    {{ num|my_filter:5 }}
{% endif %}
如何解决自定义过滤器只能传入两个参数的麻烦?

第二个参数使用列表。。。

模板继承

include关键字

{% include advertise.html %} 可以将外部html插入到该处,有助于代码复用

extends关键字

在基本版本HTML中使用block标签
home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    <title>{% block title %}这是基本模板{% endblock %}</title>
</head>
<body>
<div class="container">
    <div class="row">
        <ul class="nav nav-pills">
            <li role="presentation" class="active"><a href="#">Home</a></li>
            <li role="presentation"><a href="#">杂</a></li>
            <li role="presentation"><a href="#">关于</a></li>
        </ul>
    </div>
    <div class="row">
        {% block content %}
            <h1>空</h1>   
        {% endblock %}
    </div>
</div>
</body>
</html>

block标签的作用相当于一个占位符,后面html页面导入该页面时要替换他

在版本中,只要导入该基本版,然后填充block标签里的内容就可以使用

{% extends "base.html" %}
{% block title %}
    主页
{% endblock %}
{% block content %}
<p>这里是主页</p>
{% endblock %}

extends标签的作用是将html模板导入该页面

注意:

  • 在基本版HTML页面中,{% block %}标签包裹的内容是默认内容,就是没有设置该标签时,显示的内容
  • 如果页面想要在原来默认内容上拓展内容,就在子HTML的block标签中添加{{ block.super }}
    示例:
{% block con%}
{{ block.super }}
在原继承基础上,需要拓展的内容
{% endblock %}
  • 可以在endblock后面添加一个名字
{% block con %}
{% endblock con %}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值