初识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), ]
用()括起来表示保存为一个子组,每个子组作为一个参数(无名参数),被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> #######################
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 # 方法。
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\'
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>
shopping_car.html:
1 {% extends \'base.html\' %} 2 3 4 {% block content %} 5 <a>购物车</a> 6 {% endblock %}
ordered.html:
以上是关于初识Django的主要内容,如果未能解决你的问题,请参考以下文章