Django框架

Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。

一、django的安装实现和目录介绍

1、django实现流程

django
#安装: pip3 install django 添加环境变量 #1 创建project
django-admin startproject mysite ---mysite ---settings.py
---url.py
---wsgi.py ---- manage.py(启动文件) #2 创建APP
python mannage.py startapp app01 #3 settings配置 TEMPLATES STATICFILES_DIRS=(
os.path.join(BASE_DIR,"statics"),
) STATIC_URL = '/static/'
# 我们只能用 STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去找#4 根据需求设计代码
url.py
view.py #5 使用模版
render(req,"index.html") #6 启动项目
python manage.py runserver 127.0.0.1:8090 #7 连接数据库,操作数据
model.py

2.django的目录介绍

如下图:

目录介绍如下:

day70:
- app01
- admin Django自带后台管理相关配置
- modal 写类,根据类创建数据库表
- test 单元测试
- views 业务处理
- app02
- app03
day70
settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
urls.py ----- 负责把URL模式映射到应用程序。
manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。

二、django的基本配置

Django的配置文件(settings)

在settings文件内,有几处需要注意,分别是:

1、

2、模版

3、数据库

4、静态文件

三、路由系统:

1、单一路由对应(即一个url对应一个函数)

2、基于正则的路由

3、添加额外的参数

4、路由的分发

示例如下:

    # =======关于路由系统======
url(r'^index/', views.index),# 1、静态路由:一个url对应一个函数,url(r'^index/', views.index)对应一个函数=====> def index url(r'^edit/(\w+)/', views.edit),#2.动态路由:匹配正则url(r'^edit/(\w+)/', views.edit)====> def edit(request, a1),al代表url后面的正则 # 3、按照关键字传url(r'^add_user / (?P < a1 >\d +) /', ====> def add_user(request, a1)
# 注:终止符:^ edit$
# 伪静态:url(r'^edit/(\w+).html$', views.edit),
url(r'^app01/', include('app01.urls')),
# 4、路由分发:a.在当前url下导入include,在写url(r'^app01/', include('app01.urls')
# b.再在app01的包下面建一个urls.py文件,写入以下内容:
# from django.conf.urls import url
# from app01 import views
# urlpatterns=[
# url(r'^index.html$', views.index),
# ]
# c.在浏览器输入网址http://127.0.0.1:8000/app01/index.html即可读取index.html的内容

其url所对应的函数分别是:

def index(request):
user_list=[
"xuyuanyuan",
"bob",
"slina"
]
return render(request,"index.html",{"user_list":user_list}) def edit(request,x):
print(x)
return HttpResponse("hello") def add_user(request,a1):
from django.urls import reverse
v=reverse("xyy",a1)
return HttpResponse("ok")  

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

四 Django Views(视图函数)

http请求中产生两个核心对象:

http请求:HttpRequest对象

http响应:HttpResponse对象

所在位置:django.http

之前我们用到的参数request就是HttpRequest    检测方法:isinstance(request,HttpRequest)

1 HttpRequest对象的属性和方法:

# path:       请求页面的全路径,不包括域名
#
# method: 请求中使用的HTTP方法的字符串表示。全大写表示。例如
#
# if req.method=="GET":
#
# do_something()
#
# elseif req.method=="POST":
#
# do_something_else()
#
# GET: 包含所有HTTP GET参数的类字典对象
#
# POST: 包含所有HTTP POST参数的类字典对象
#
# 服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
# HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
# if req.POST来判断是否使用了HTTP POST 方法;应该使用 if req.method=="POST"
#
#
#
# COOKIES: 包含所有cookies的标准Python字典对象;keys和values都是字符串。
#
# FILES: 包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中 name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
#
# filename: 上传文件名,用字符串表示
# content_type: 上传文件的Content Type
# content: 上传文件的原始内容
#
#
# user: 是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
# 没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
# 可以通过user的is_authenticated()方法来辨别用户是否登陆:
# if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
# 时该属性才可用
#
# session: 唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。 #方法
get_full_path(), 比如:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123
req.path:/index33

2 HttpResponse对象:

对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象。

HttpResponse类在django.http.HttpResponse

在HttpResponse对象上扩展的常用方法:

页面渲染:         render()
页面跳转: redirect("路径")
locals(): 可以直接将函数中所有的变量传给模板

示例:

例如在urls.py文件内有如下内容:

 url(r'^teacher/',views.teacher),
url(r'^add_teacher/',views.add_teacher),

则在views.py文件内是:

def teacher(request):
# models.Teacher.objects.create(tname="alex")
# models.Teacher.objects.create(tname="egon")
# models.Teacher.objects.create(tname="wusir")
teacher_list=models.Teacher.objects.all() return render(request,"teacher.html",{"teacher_list":teacher_list})
def add_teacher(request):
teacher_name=input("请输入你要添加的老师名字:").strip()
models.Teacher.objects.create(tname=teacher_name)
return redirect("/teacher/")

总结:

关于render和redirect的区别是:

1 render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分
除了写在teacher的视图函数中 2 redirect: url直接跳转到/teacher/

补充:

关于视图函数内的CBV(基于类的)和FBV(基于函数)

1、FBV:(在views.py文件内定义的是一个个的函数)

示例:

def index(request):
user_list=[
"xuyuanyuan",
"bob",
"slina"
]
return render(request,"index.html",{"user_list":user_list}) 

2、CBV(在views.py文件内定义的是类)

示例(在views.py文件内定义的是类)

class Login(View):
"""
get 查
post 创建
put 更新
delete 删除
""" def get(self,request):
# return HttpResponse("login_get")
return render(request,"login.html") def post(self,request):
print(request.POST.get("username"))
return HttpResponse("login_post")

  

五、Template ---模板

模板系统介绍

模板系统的组成:HTML代码和逻辑控制代码

逻辑控制代码可以理解是django模板语言

django的模板语言组成

  1. 变量(使用双大括号来引用变量):

  2. 标签(tag)的使用(使用大括号和百分比的组合来表示使用tag)
  3. 模板继承

模板语言之变量

语法:

{{var_name}}   var_name 指变量名

模版语言

 模板中也有自己的语言,该语言可以实现数据展示

    • {{ item }}
    • {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
        forloop.counter
        forloop.first
        forloop.last
    • {% if ordered_warranty %}  {% else %} {% endif %}
    • 母板:{% block title %}{% endblock %}
      子板:{% extends "base.html" %}
         {% block title %}{% endblock %}
    • 帮助方法:
      {{ item.event_start|date:"Y-m-d H:i:s"}}
      {{ bio|truncatewords:"30" }}
      {{ my_list|first|upper }}
      {{ name|lower }}

模板引入和继承

1、母板:(即模板的继承)

常见的 Web 开发问题: 在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?

解决该问题的传统做法是使用 服务器端的 includes ,你可以在 HTML 页面中使用该指令将一个网页嵌入到另一个中。 事实上, Django 通过刚才讲述的 {% include %} 支持了这种方法。 但是用 Django 解决此类问题的首选方法是使用更加优雅的策略—— 模板继承 。

本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。

如果子板不自定义块,默认会继承母板的所有内容(包括模板的css,js),如果子板要修改css或js文件,在相应地方加块,就可以了

示例:layout.html是母板,classes.html是子板(需要将classes.html内的内容填充至layout.html的框架内,则可以按照如下图所示使用)

注:

母板

{% block 自定义块名%}

子板的块

{% block 母板中相应设置的块名 }

{% block %}  内容 {% endblock %}的标签也是成对出现

使用继承的注意事项:

  1. 创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。
  2. 为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。这些模板对base.html 进行拓展,并包含区域特定的风格与设计。
  3. 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。

模板继承的一些诀窍:

    1. 如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。
    2. 一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。
    3. 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。
    4. 不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

2、include(导入小组件===>模板引入)

{% include %}该标签允许在(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串。 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重复。

第一步:建一个common.html文件,写入大家都需要使用的共同内容:

示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<h3>大家都需要用的小组件</h3>
<div class="title">标题:{{ name }}</div>
<div class="content">内容:{{ name }}</div>
</div> </body>
</html>

第二步:当有html文件需要使用这个小组件时

示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
{# 需要用的小组件:将其引入即可#}
{% include 'common.html' %}
<h1>用户登录</h1>
<form method="post" action="/login.html">
{% csrf_token %}
<div>
用户名:<input type="text" name="uname">
</div>
<div>
密 码:<input type="password" name="pwd"><br>
</div>
<input type="submit" value="登录">{{ mag }} </form>
{# 在这个也需要用小组件#}
{% include 'common.html' %}
</div> {% include 'common.html' %} </body>
</html>

3、模板自定义函数:

(1) simple_filter
最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
可以做条件判断

(2) simple_tag
无限制: {% 函数名 参数 参数%}

a、在app中创建templatetags模块

b、创建任意 .py 文件,如:test.py

示例:

在test.py文件内写入以下内容:

from django import template
register=template.Library()#register这个变量名是固定的,不可修改 @register.filter
def my_upper(value): return value.upper() @register.filter
def join(value,arg):
return value+arg @register.filter
def my_bool(value):
return False @register.simple_tag
def my_lower(value,a1,a2,a3): return value + a1 + a2 + a3 #两者的区别:
# 1、使用@register.filter只能接受2个参数,而使用@register.simple_tag可以接收无数个参数
# 2、两者在前端的调用取值不同:分别是: <h1>filter</h1>
# {{ name|my_upper }}
# {{ name|join:"hahah"}}
#
# <h1>simple_tag</h1>
# {% my_lower "xuyuanyuan" "a1" "a2" "a3" %}
# 3、使用@register.filter,当前前端使用时,可以进行进行条件语句的if 内,而@register.simple_tag不能用于条件语句

  

c、在使用自定义simple_tag的html文件中导入之前创建的 test.py 文件名

{% load test %}  

d、使用simple_tag(再建立一个test.html文件,在其内写入:)

{% load test %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{# - simple_filter#}
{# - 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}#}
{# - 可以做条件判断#}
<h1>filter</h1>
{{ name|my_upper }}
{{ name|join:"hahah"}} <h1>filter用于if语句示例</h1>
{% if name|my_bool %}
<h3>真的啊</h3>
{% else %}
<h3>假的啊</h3>
{% endif %} {# - simple_tag#}
{# - 无限制: {% 函数名 参数 参数%}#}
<h1>simple_tag</h1>
{% my_lower "xuyuanyuan" "a1" "a2" "a3" %} </body>
</html>  

e、在settings中配置当前app,不然django无法找到自定义的simple_tag  

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',#当前的app
'app02',
]

其执行结果是:

最新文章

  1. Windows 2008 R2 安装 Windows phone 7 开发环境
  2. 自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试
  3. Unity 2D Skeletal Animation
  4. 03SpringMvc_自定义的spring.xml配置文件和逻辑视图名
  5. shell之并行
  6. [转]Webservice client timeout
  7. iOS7之定制View Controller切换效果
  8. centos系统python升级2.7.3
  9. Unity3D 之UGUI 按钮
  10. JDK自带方法实现消息摘要运算
  11. 【转】Java中如何遍历Map对象的4种方法
  12. sql server2008附加数据库5120错误
  13. Android SDK下载和更新失败的解决方法!!!
  14. 开启属于你的GNOME桌面
  15. Keil提示premature end of file错误 无法生成HEX文件
  16. 【c语言】分配内存与释放内存
  17. 学习笔记CB003:分块、标记、关系抽取、文法特征结构
  18. Mac OS X 避免产生临时文件 .DS_Store
  19. a small notepad++ plugin to support doxygen 1key generate
  20. WINFROM窗体实现圆角

热门文章

  1. C#中的静态常量(const)和动态常量(static和readonly)用法和区别
  2. 【转】ssh登录原理以及ssh免密码登陆
  3. 【SPOJ】QTREE7(Link-Cut Tree)
  4. ZOJ3899 State Reversing 【线段树 + NTT】
  5. MySQL 5.5 主从复制
  6. Zookeeper(二) zookeeper集群搭建 与使用
  7. 专题训练之数位DP
  8. python基础----面向对象的程序设计(五个阶段、对小白的忠告、关于OOP常用术语)、类、对象
  9. python创建多维列表
  10. 【题解】Inspection UVa 1440 LA 4597 NEERC 2009