初识Django

Posted oliver.lee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识Django相关的知识,希望对你有一定的参考价值。

返回顶部

使用框架简单快速开发特定的系统。

pip freeze > requirements.txt

pip install -r requirements.txt

一 MVC和MTV模式

 

二 简介

Django时有Python开发的一个免费的开源网站框架,可以用于快速搭建高性能、优雅的网站。

Django框架的特点:

  • 强大的数据库功能
  • 自带强大的后台功能
  • 通过正则匹配随意定义的网址
  • 强大易扩展的模板系统
  • 缓存系统
  • 国际化

三 Django安装方式

1.利用pip安装Django。

oliver@oliver-G460:~$ sudo pip3 install Django

2.利用源码包安装Django。

oliver@oliver-G460:~$ tar -zxvf django-1.10.xx.tar.gz

 解压后进入目录,执行:

python3 setup.py install

3.利用Linux自带源安装Django。

sudo apt-get install python3-django

 

检查Django是否安装成功:

oliver@oliver-G460:~$ python3
Python 3.5.2 (default, Sep 10 2016, 08:21:44) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.VERSION
(1, 10, 2, \'final\', 0)

 

 如果希望安装不同版本的Django环境,则需要通过virtualenv来管理多个开发环境。

四 Django项目创建

方式一:用命令创建项目和app

1. 创建一个新的Django项目

2. 创建app

python3 manage.py startapp app-name 或 django-admin.py startapp app-name

需要注意的是,通过命令行创建的项目,在settings.py中,如app名称和模板路径及templates目录等信息要自己添加。

方式二:用Pycharm创建

在File→New Project中选择Django,输入项目名称mysite和应用名称myApp,完成创建。

创建完成后, 用Pycharm打开项目,查看项目和app目录文件

  • manage.py:用于管理Django站点。
  • settings.py:项目所有的配置信息,包含项目默认设置,数据库信息,调试标识以及其它工作变量等。
  • urls.py:负责把URL映射到视图函数,即路由系统。
  • wsgi.py:内置runserver命令的WSGI应用配置。

 五 Django urls(路由系统)

 即urls.py文件。其本质是建立url与其所调用的视图函数的映射关系,以此来规定访问什么网址去对应什么内容,执行哪个视图函数。

urlpatterns = [
        url(正则表达式,views视图函数,[参数],[别名]),   
]

 说明(括号中四部分的意义):

  • 正则表达式字符串来匹配浏览器发送到服务端的URL网址
  • 可调用的视图函数对象。先引入(import)再使用
  • 要传给视图函数的默认参数(字典形式)
  • name,即别名。html中form表单参数action属性值使用此别名后,即便url发生变化,也无需在HTML中批量进行修改。

1 URL配置举例:

from django.conf.urls import url
from django.contrib import admin

from app01 import views

urlpatterns = [

    url(r\'^articles/2003/$\', views.special_case_2003),

    #url(r\'^articles/[0-9]{4}/$\', views.year_archive),

    url(r\'^articles/([0-9]{4})/$\', views.year_archive),  #no_named group

    url(r\'^articles/([0-9]{4})/([0-9]{2})/$\', views.month_archive),

    url(r\'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$\', views.article_detail),

]
View Code

用()括起来表示保存为一个子组,每个子组作为一个参数(无名参数),被views.py中的对应函数接收。参数个数与视图函数中的形参个数要保持一致。

 

(注意:当匹配到第一个url后立即返回,不再向下查找匹配。)

2 带命名的组Named group(?P<>)用法

?P<group_name> 表示带命名的参数,例如:将year=\'2016\'作为一个整体传个视图函数。此处的组名称必须与视图函数中的形参名称一致。由于有参数名称与之对应,所以视图函数有多个形参时,不需要考虑参数的先后顺序。

from django.conf.urls import url
  
from . import views
  
urlpatterns = [
    url(r\'^articles/2003/$\', views.special_case_2003),
    url(r\'^articles/(?P<year>[0-9]{4})/$\', views.year_archive),  # year=2016
    url(r\'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$\', views.month_archive),
    url(r\'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$\', views.article_detail),
]

3 默认参数(可选)

如下所示,如果请求地址为/blog/2016,表示将year=\'2016\',foo=\'bar\'传给视图函数,视图函数中必须有相同名称的形参来接收值。

from django.conf.urls import url
from . import views
  
urlpatterns = [
    url(r\'^blog/(?P<year>[0-9]{4})/$\', views.year_archive, {\'foo\': \'bar\'}),
]

4 name别名(可选)

 固定用法:

url(r\'^/index/\',views.index,name=\'bieming\')

如果url中的路径修改为/index2/,对应的模板,甚至还视图中的跳转,以及 models.py 中也可能有获取网址的地方。每个地方都要改,修改的代价很大,一不小心,有的地方没改过来,那个就不能用了。

因此,在需要跳转或获取网址的地方,使用别名设置的名称,以后便可以随意修改url了。

urlpatterns = [
    url(r\'^index\',views.index,name=\'bieming\'),
    url(r\'^admin/\', admin.site.urls),
    # url(r\'^articles/2003/$\', views.special_case_2003),
    url(r\'^articles/([0-9]{4})/$\', views.year_archive),
    # url(r\'^articles/([0-9]{4})/([0-9]{2})/$\', views.month_archive),
    # url(r\'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$\', views.article_detail),

]
###################

def index(req):
    if req.method==\'POST\':
        username=req.POST.get(\'username\')
        password=req.POST.get(\'password\')
        if username==\'alex\' and password==\'123\':
            return HttpResponse("登陆成功")



    return render(req,\'index.html\')

#####################

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
     <form action="{% url \'bieming\' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################
View Code

 5 URLconf

一个网站包含成千上万个URL,如果所有的URL映射都放在一个文件下,很可能会出错,也不便与维护。

因此,我们在每个app应用下分别创建一个urls目录,将不同的请求分发给不同app下的urls去匹配,如:对于/blog/index/请求直接交给‘blog.urls’去处理,清晰明确,更方便管理。

 

六 Django views(视图函数)

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

http请求:HttpRequest对象

http响应:HttpResponse对象

所在位置:django.http

request就是指HttpRequest。

1 HttpRequest对象的属性和方法

 

属性 描述
path 请求页面的全路径,不包括域名—例如, "/music/bands/the_beatles/"。
method 请求中使用的HTTP方法的字符串表示。全大写表示。
GET 包含所有HTTP GET参数的类字典对象
POST 包含所有HTTP POST参数的类字典对象
REQUEST 为了方便,该属性是POST和GET属性的集合体,但是有特殊性,先查找POST属性,然后再查找GET属性
COOKIES 包含所有cookies的标准Python字典对象。Keys和values都是字符串。
FILES 包含所有上传文件的类字典对象。FILES中的每个Key都是<input type="file" name="" />标签中name属性的值. FILES中的每个value 同时也是一个标准Python字典对象,包含下面三个Keys:(Filename: 上传文件名,用Python字符串表示;content-type: 上传文件的Content type;content: 上传文件的原始内容)注意:只有在请求方法是POST,并且请求页面中<form>enctype="multipart/form-data"属性时FILES才拥有数据。否则,FILES 是一个空字典。
META 包含所有可用HTTP头部信息的字典,例如:(CONTENT_LENGTH,CONTENT_TYPE,QUERY_STRING: 未解析的原始查询字符,串,REMOTE_ADDR: 客户端IP地址REMOTE_HOST: 客户端主机名,SERVER_NAME: 服务器主机名,SERVER_PORT: 服务器端口);META 中这些头加上前缀HTTP_最为Key, 例如:(HTTP_ACCEPT_ENCODING,HTTP_ACCEPT_LANGUAGE,HTTP_HOST: 客户发送的HTTP主机头信息,HTTP_REFERER: referring页,HTTP_USER_AGENT: 客户端的user-agent字符串,HTTP_X_BENDER: X-Bender头信息)
user 是一个django.contrib.auth.models.User 对象,代表当前登录的用户。如果访问用户当前没有登录,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。见例子1
session 唯一可读写的属性,代表当前会话的字典对象。只有激活Django中的session支持时该属性才可用。
raw_post_data 原始HTTP POST数据,未解析过。 高级处理时会有用处。

 

method 描述
__getitem__(key) 返回GET/POST的键值,先取POST,后取GET。如果键不存在抛出 KeyError。这是我们可以使用字典语法访问HttpRequest对象。例如:request["foo"]等同于先request.POST["foo"] 然后 request.GET["foo"]的操作。
has_key() 检查request.GET or request.POST中是否包含参数指定的Key。
get_full_path() 返回包含查询字符串的请求路径。例如, "/music/bands/the_beatles/?print=true"
is_secure() 如果请求是安全的,返回True,就是说,发出的是HTTPS请求。
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()(推荐)        或         render_to_response(),
页面跳转:         redirect("路径")
locals():    可以直接将函数中所有的变量传给模板

七 Django templates(模板)

 模板由HTML+逻辑控制代码组成。

1 变量

使用双大括号来引用变量

语法格式:       {{var_name}}

2 Template和Context对象

渲染操作流程:

一旦创建Template对象之后,可以用context传递数据给它,它是一系列变量和它们值的集合,模板使用它来赋值模板变量标签和执行块标签

context在django里表现为Context类,在django.template模块中

Context类构造是一个可选参数:一个字典映射变量和它们的值

创建一系列Context对象之后,调用Template对象的render()方法并传递Context对象来填充模板

同一个模板渲染多个context:

1 >>>from django,template import Template,Context
2 >>>t=Template("My name is {{name}},I love{{language}}")
3 >>>c=Context({\'name\':\'BeginMan\',\'language\':\'Python/Js/C#\'})
4 >>>t.render(c)
5 --------------------------------output----------------------------------------------
6 My name is BeginMan ,I love Python/Js/C#


推荐写法:

def current_time(req):

    now=datetime.datetime.now()

    return render(req, \'current_datetime.html\', {\'current_date\':now})    # 字典部分指定就是Context对象,render()方法将Context对象的键值传递给模板,并填充模板。

 3 深度变量查找

context不仅能传递简单的参数(字符串),也可以传递列表和字典对象。

 1 #最好是用几个例子来说明一下。
 2 # 首先,句点可用于访问列表索引,例如:
 3 
 4 >>> from django.template import Template, Context
 5 >>> t = Template(\'Item 2 is {{ items.2 }}.\')
 6 >>> c = Context({\'items\': [\'apples\', \'bananas\', \'carrots\']})
 7 >>> t.render(c)
 8 \'Item 2 is carrots.\'
 9 
10 #假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点:
11 >>> from django.template import Template, Context
12 >>> person = {\'name\': \'Sally\', \'age\': \'43\'}
13 >>> t = Template(\'{{ person.name }} is {{ person.age }} years old.\')
14 >>> c = Context({\'person\': person})
15 >>> t.render(c)
16 \'Sally is 43 years old.\'
17 
18 #同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有
19 #year 、 month 和 day 几个属性,你同样可以在模板中使用句点来访问这些属性:
20 
21 >>> from django.template import Template, Context
22 >>> import datetime
23 >>> d = datetime.date(1993, 5, 2)
24 >>> d.year
25 >>> d.month
26 >>> d.day
27 >>> t = Template(\'The month is {{ date.month }} and the year is {{ date.year }}.\')
28 >>> c = Context({\'date\': d})
29 >>> t.render(c)
30 \'The month is 5 and the year is 1993.\'
31 
32 # 这个例子使用了一个自定义的类,演示了通过实例变量加一点(dots)来访问它的属性,这个方法适
33 # 用于任意的对象。
34 >>> from django.template import Template, Context
35 >>> class Person(object):
36 ...     def __init__(self, first_name, last_name):
37 ...         self.first_name, self.last_name = first_name, last_name
38 >>> t = Template(\'Hello, {{ person.first_name }} {{ person.last_name }}.\')
39 >>> c = Context({\'person\': Person(\'John\', \'Smith\')})
40 >>> t.render(c)
41 \'Hello, John Smith.\'
42 
43 # 点语法也可以用来引用对象的方法。 例如,每个 Python 字符串都有 upper() 和 isdigit()
44 # 方法,你在模板中可以使用同样的句点语法来调用它们:
45 >>> from django.template import Template, Context
46 >>> t = Template(\'{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}\')
47 >>> t.render(Context({\'var\': \'hello\'}))
48 \'hello -- HELLO -- False\'
49 >>> t.render(Context({\'var\': \'123\'}))
50 \'123 -- 123 -- True\'
51 
52 # 注意这里调用方法时并* 没有* 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的
53 # 方法。
View Code

4 变量过滤器filter

语法格式:      {{obj|filter:param}}
 1 # 1  add          :   给变量加上相应的值
 2    #
 3    # 2  addslashes   :    给变量中的引号前加上斜线
 4    #
 5    # 3  capfirst     :    首字母大写
 6    #
 7    # 4  cut          :   从字符串中移除指定的字符
 8    #
 9    # 5  date         :   格式化日期字符串
10    #
11    # 6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值
12    #
13    # 7  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值
14 
15 
16 #实例:
17 
18 #value1="aBcDe"
19 {{ value1|upper }}
20 
21 #value2=5
22 {{ value2|add:3 }}
23 
24 #value3=\'he  llo wo r ld\'
25 {{ value3|cut:\' \' }}
26 
27 #import datetime
28 #value4=datetime.datetime.now()
29 {{ value4|date:\'Y-m-d\' }}
30 
31 #value5=[]
32 {{ value5|default:\'空的\' }}
33 
34 #value6=\'<a href="#">跳转</a>\'
35 
36 {{ value6 }}
37 
38 {% autoescape off %}
39   {{ value6 }}
40 {% endautoescape %}
41 
42 {{ value6|safe }}
43 
44 {{ value6|striptags }}
45 
46 #value7=\'1234\'
47 {{ value7|filesizeformat }}
48 {{ value7|first }}
49 {{ value7|length }}
50 {{ value7|slice:":-1" }}
51 
52 #value8=\'http://www.baidu.com/?a=1&b=3\'
53 {{ value8|urlencode }}
54     value9=\'hello I am yuan\'
View Code

5 常用标签(tag)

语法格式:      {% tags %}

(1)  {% if %}

 

(2)  {% for %}

 

(3)  {% csrf_token %}

 

(4)  {% url %} :引用路由配置的地址

 

(5)  {% with %} :用简短的变量名代替复杂的变量名

 

(6) {% verbatim %} :禁止render

 

(7) {% load %} :加载标签库

 

6 自定义filter和simple_tag

(1)在app下创建templatetags目录或模块,目录名称必须这样写。

(2)创建.py文件,如my_tags。(其中,register名称不可改变)

(3)在使用自定义filter和simple_tag的html文件之前,通过 {% load my_tags %}导入前面自己创建的my_tags标签库。(注意:settings中INSTALLED_APPS中必须添加当前的app名称,否则找不到自定义的tags)

(4)调用自定义的filter和simple_tag。

 

filter可以用在if等语句后,simple_tag不可以:

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

7 extend模板继承

将shopping_car.html和ordered.html中大量重复的代码提取出来,写入base.html中,不同的部分分别写在各自模板中,通过extends继承base.html中的公共部分。

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         *{
 8             margin: 0;
 9         }
10 
11         .top{
12             height: 45px;
13             background-color: darkblue;
14         }
15 
16         .menu{
17             width: 20%;
18             height: 700px;
19             background-color: cornflowerblue;
20             float: left;
21             margin-top: 5px;
22         }
23 
24         .menu a{
25             display: block;
26             text-align: center;
27         }
28 
29         .content{
30             width: 80%;
31             height: 700px;
32             float: left;
33             margin-top: 5px;
34             background-color: lightgray;
35         }
36     </style>
37 </head>
38 <body>
39     <div class="top"></div>
40     <div class="menu">
41         <a href="/shopping_car/">Shopping Car</a>
42         <a href="/ordered/">Ordered</a>
43     </div>
44     <div class="content">
45         {% block content %}
46         {% endblock %}
47     </div>
48 </body>
49 </html>
base.html

shopping_car.html:

1 {% extends \'base.html\' %}
2 
3 
4 {% block content %}
5  <a>购物车</a>
6 {% endblock %}

ordered.html: