从Python到Django入门

上一篇写socket实例的时候切身感受到了python的简单,于是最近想写一些关于python的文章。那就像之前的那些文章那样,整个入门教程吧。

前言

写这篇基本是没有自己的思想的,纯粹是为了学习python,所以下面的内容基本都是从别处搬来的。网上有两篇写的很好的python学习的中文教程,一篇是廖雪峰的,一篇是Vamei的。这两篇对我学习python帮助巨大,但我这篇不想抄他们的。

我要抄的是一本叫做Python Web Development with Django书上的,这本书是外国人写的介绍Django开发Web程序的(书比较老了,写例子时要改成较新的),这里直接照搬其第一部分,作为Python的入门文章,所以有了这篇的题目。

Python练习

Python是编程新手的最好的语言,因为它足够简单。

直接上个代码感受下吧。

1
2
3
4
5
>>> print 'hello, world.'
>>> for word in ['capitalize','these','words']:
... print word.upper()
>>> for i in range(0,5):
... print i

基础

注释

1
2
3
# this entire line is a comment
foo = 1 # short comment: assign int 1 to 'foo'
print 'Python and %s are number %d' % ('Django,foo)

变量及赋值

1
2
foo = 'bar'
foo = 10

运算符:算数运算符+-*/等,赋值运算符+=,-=,*=等(不支持++,–),关系运算符<,>=,==,!=等,逻辑运算符and,or,not

1
2
3
show_output = True
if show_output and foo==1:
print 'hello'

标准类型

布尔型

1
2
3
4
5
6
7
8
9
10
11
>>> download_complete = False
>>> bool(download_complete)
False
>>> bool(-1.23)
True
>>> bool(0.0)
False
>>> bool("")
False
>>> bool([None,0])
True

数值型:两种主要的数值类型intfloat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> 1/2
0
>>> 1.0/2.0
0.5
>>> 1//2
0
>>> 1.0//2.0
0
>>> int('123')
123
>>> int(45.67)
45
>>> round(1.16,1) #四舍五入
1.2
>>> fload(10)
10.0
>>> ord('a')
97
>>> chr(65)
A
>>> divmod(15,6) #除余
(2,3)

序列和迭代

字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
>>> s='Python'
>>> s
'Python'
>>> s[0]
'P'
>>> s[4]
'o'
>>> s[-1]
'n'
>>> s[1:4]
'yth'
>>> s[2:4]
'th'
>>> s[:4]
'Pyth'
>>> s[3:]
'hon'
>>> s[:]
'Python'
>>> str(s)
'Python'
>>> 'Python and'+' '+'Django are cool'
'Python and Django are cool'
>>> '-'*40
'----------------------------------------'
>>> 'an' in 'Django'
True
>>> 'xyz' not in 'Django'
True

列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
>>> book=['Python','Development',8]
>>> book.append(2008)
>>> book
['Python', 'Development', 8, 2008]
>>> book.insert(1,'Web')
>>> book
['Python', 'Web', 'Development', 8, 2008]
>>> book.insert(1,'Web')
>>> book
['Python', 'Web', 'Development', 8, 2008]
>>> book[3]
8
>>> 'Python' in book
True
>>> 'Django' in book
False
>>> book.remove(8)
>>> book.pop(-1)
2008
>>> book
['Python', 'Web', 'Development']
>>> book*2
['Python', 'Web', 'Development', 'Python', 'Web', 'Development']
>>> book.extend(['with','Django'])
>>> book
['Python', 'Web', 'Development', 'with', 'Django']
>>> book.sort()
>>> book
['Development', 'Django', 'Python', 'Web', 'with']
>>> data=[x+1 for x in range(10)]
>>> data
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> even_nums=[x for x in range(10) if x%2==0]
>>> even_nums
[0, 2, 4, 6, 8]
>>> even_nums=(x for x in range(10000) if x%2==0)
>>> even_nums
<generator object <genexpr> at 0x0265FF58>

字符串函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
>>> s='Django is cool'
>>> s.split()
['Django', 'is', 'cool']
>>> words=s.split()
>>> ' '.join()
>>> ' '.join(words)
'Django is cool'
>>> '-'.join(words)
'Django-is-cool'
>>> s.upper()
'DJANGO IS COOL'
>>> s.upper().isupper()
True
>>> s.title()
'Django Is Cool'
>>> s.capitalize()
'Django is cool'
>>> s.count('o')
3
>>> s.find('go')
4
>>> s.find('xxx')
-1
>>> s.startswith('Python')
False
>>> s.replace('Django','Python')
'Python is cool'

字符串其他

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> mystr=u'This is unicode'
>>> mystr
u'This is unicode'
>>> print mystr
This is unicode
>>> str(mystr)
'This is unicode'
>>> hi='''hi
... there'''
>>> hi
'hi\nthere'
>>> print hi
hi
there

元组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> a=("one","two")
>>> a[0]
'one'
>>> b=("just-one")
>>> b[0]
'j'
>>> b=("just-one",)
>>> b[0]
'just-one'
>>> c='just-one',
>>> c
('just-one',)
>>> c[0]
'just-one'

字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
>>> book={'title':'Python Web Development','year':2008}
>>> book
{'year': 2008, 'title': 'Python Web Development'}
>>> 'year' in book
True
>>> 2008 in book
False
>>> book.get('pub','N/A')
'N/A'
>>> book['pub']='Wesley'
>>> book.get('pub','N/A')
'Wesley'
>>> for key in book:
... print key,':',book[key]
...
year : 2008
pub : Wesley
title : Python Web Development
>>> del book['year']
>>> book
{'pub': 'Wesley', 'title': 'Python Web Development'}
>>> len(book)
2
>>> for k in book.keys():print k
...
pub
title
>>> for v in book.values():print v
...
Wesley
Python Web Development
>>> for i in book.items():print i
...
('pub', 'Wesley')
('title', 'Python Web Development')

流程控制

条件判断

1
2
3
4
5
6
7
data = raw_input('Enter "y" or "n": ')
if data[0] == 'y':
print 'yes'
elif data[0] == 'n':
print 'no'
else:
print 'Invalid key entered'

循环

1
2
3
4
5
6
7
i = 0
while i < 5:
print i
i += 1
data = (123, 'abc', 3.14)
for i,value in enumerate(data):
print i,value

异常捕获

1
2
3
4
5
6
7
8
try:
process_some_data()
except (TypeError, ValueError), e:
print "ERROR: you provide invalid data", e
except ArithmeticError, e:
print "ERROR: some math error occurred", e
except Exception, e:
print "ERROR: you provide invalid data", e

finally

1
2
3
4
5
try:
get_mutex()
do_some_stuff()
finally:
free_mutex()

省事的写法

1
2
3
4
5
6
try:
pass
except:
pass
finally:
pass

抛出异常

1
2
3
4
5
6
7
8
9
def foo(must_be_positive_int):
"""foo() -- take positive integer and process it"""
# check if integer
if not isinstance(must_be_positive_int, int):
raise TypeError("ERROR foo(): must pass in an integer!")
# check if positive
if must_be_positive_int < 1:
raise ValueError("ERROR foo(): integer must be greater than zero!")
# normal processing here

文件操作

1
2
3
4
5
6
7
8
f = open('1.txt', 'w')
f.write('foo\n')
f.write('bar\n')
f.close()
f = open('1.txt', 'r')
for line in f:
print line.rstrip()
f.close()

函数

函数声明和调用

1
2
3
def foo(x):
print x
foo(12)

一个有用的函数

1
2
3
4
5
6
7
8
9
10
11
12
import httplib
def check_web_server(host, port, path):
h = httplib.HTTPConnection(host, port)
h.request('GET', path)
resp = h.getresponse()
print 'HTTP Response:'
print ' status =', resp.status
print ' reason =', resp.reason
print 'HTTP Headers:'
for hdr in resp.getheaders():
print ' %s: %s' % hdr
check_web_server(port=80, path='/', host='www.python.org')

一个默认参数的例子

1
2
3
4
5
6
7
8
9
10
>>> def func(arg=[]):
... arg.append(1)
... print arg
...
>>> func()
[1]
>>> func()
[1, 1]
>>> func()
[1, 1, 1]

函数引用

1
2
3
4
5
6
7
8
def bar():
print 'bar'
bar()
baz = bar
baz()
func_list = [bar, baz]
for f in func_list:
f()

匿名函数

1
2
3
4
5
>>> starList=[('bruce','li'),('jack','cheng'),('jet','li'),('danniel','yin')]
>>> sorted(starList)
[('bruce', 'li'), ('danniel', 'yin'), ('jack', 'cheng'), ('jet', 'li')]
>>> sorted(starList, key=lambda star:star[1])
[('jack', 'cheng'), ('bruce', 'li'), ('jet', 'li'), ('danniel', 'yin')]

可变参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>>> def fun1(a,b,c):
... print a,b,c
...
>>> fun1(1,2,3)
1 2 3
>>> l=['a','b','c']
>>> fun1(*l)
a b c
>>> d={'a':1,'b':2,'c':3}
>>> fun1(**d)
1 2 3
# 上面是传递参数的一种方式不是可变参数
# 下面看真正的可变参数
>>> def fun2(*args,**kwargs):
... print args
... print kwargs
...
>>> fun2(1,2,3)
(1, 2, 3)
{}
>>> fun2(1,2,3,a='1',b='2',c='3')
(1, 2, 3)
{'a': '1', 'c': '3', 'b': '2'}
>>> fun2(*l,**d)
('a', 'b', 'c')
{'a': 1, 'c': 3, 'b': 2}

装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> def foo():
... print 'foo run'
...
>>> foo()
foo run
>>> def log(func):
... def wrapper():
... print '%s() call begin'%func.__name__
... func()
... print '%s() call end'%func.__name__
... return wrapper
...
>>> @log
... def foo1():
... print 'foo1 run'
...
>>> foo1()
foo1() call begin
foo1 run
foo1() call end

面向对象

类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class AddressBookEntry(object):
version = 0.1
def __init__(self, name, phone):
self.name = name
self.phone = phone
def update_phone(self, phone):
self.phone = phone
# 创建对象
john = AddressBookEntry('John Doe', '408-555-1212')
jane = AddressBookEntry('Jane Doe', '650-555-1212')
# 实例调用
john.update_phone('510-555-1212')
john.phone
# 动态实例属性
john.xxx = 'abc'
john.xxx

类继承

1
2
3
4
5
class EmployeeAddressBookEntry(AddressBookEntry):
def __init__(self, name, phone, id, social):
AddressBookEntry.__init__(self, name, phone)
self.empid = id
self.ssn = social

内部类

1
2
3
class MyClass(object):
class InnerClass:
pass

总结

以上是Python的入门教程,后面介绍Django入门。

Django快速上手

Django声称自己是目前最完美的Web开发框架。本章整一个使用Django建立Blog站点的例子,看看Django到底怎么完美了。

安装

我的python版本

1
2
C:\Users\Administrator>python --version
Python 2.7.12

常用安装方式

1
2
> pip install Django #安装最新版本
> pip install Django==1.8.2 #安装指定版本

我的网络不行,于是我是这么装的

1
2
#解压安装包Django-1.8.2.tar.gz
> python setup.py install

验证安装是否成功

1
2
> python -c "import django;print django.VERSION"
(1, 8, 2, 'final', 0)

搭建博客

前面一直是在windows下写的,到这里突然发现在windows下来回切换目录还挺费劲,于是转到linux下了。这是我linux的环境:

1
2
3
4
$ python -V
Python 2.7.5
$ python -c 'import django;print django.get_version()'
1.11.6

下面是建立博客站点的过程。

创建工程

执行如下命令创建工程mysite:

1
$ django-admin startproject mysite

创建成功后看看工程目录结构

1
2
3
4
5
6
7
8
$ tree mysite
mysite
├── manage.py
└── mysite
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py

相关文件在后面会用到,这里就不介绍了。

运行开发服务

执行命令运行工程。

1
2
$ cd mysite
$ python manage.py runserver

执行后会显示如下信息:

1
2
3
4
May 11, 2018 - 08:15:26
Django version 1.11.6, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

创建博客应用

执行命令创建博客应用。

1
$ python manage.py startapp blog

这时会在工程目录mysite下生成出一个blog应用目录,默认也建立好了几个文件。

创建模型

创建模型就是到blog目录下修改models.py文件,修改内容如下:

vim blog/models.py

1
2
3
4
5
6
7
8
9
10
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.
class BlogPost(models.Model):
title = models.CharField(max_length=150)
body = models.TextField()
timestamp = models.DateTimeField()

设置数据库

首先要对mysite/settings.py做一处修改,加入blog应用。

1
2
3
4
5
6
7
8
9
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]

然后还是修改该配置文件,修改数据库(这里用的是默认的sqlite3):

1
2
3
4
5
6
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

创建相关表

执行命令:

1
2
$ python manage.py migrate
$ python manage.py makemigrations

这样会根据之前创建的模型自动创建数据库表。

admin

修改blog/admin.py,修改如下:

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import admin
from .models import BlogPost

# Register your models here.
#admin.site.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'timestamp')
admin.site.register(BlogPost, BlogPostAdmin)

执行命令创建超级用户:

1
$ python manage.py createsuperuser

查看mysite/urls.py下是否有相应记录。

1
2
3
4
5
6
from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
url(r'^admin/', admin.site.urls),
]

这样后就可以用创建的用户登录网站进行BlogPost数据表管理了http://localhost:8000/admin

制作博客显示页

在blog目录下创建templates目录,在其下创建模板文件。

base.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<style type="text/css">
body { color: #efd; background: #453; padding: 0 5em; margin: 0 }
h1 { padding: 2em 1em; background: #675 }
h2 { color: #bf8; border-top: 1px dotted #fff; margin-top: 2em }
p { margin: 1em 0 }
</style>
<body>
<h1>mysite.example.com</h1>
{% block content %}
{% endblock %}
</body>
</html>

archive.html

1
2
3
4
5
6
7
8
{% extends "base.html" %}
{% block content %}
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.timestamp }}</p>
<p>{{ post.body }}</p>
{% endfor %}
{% endblock %}

编写视图方法,修改blog/views.py文件:

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from .models import BlogPost

# Create your views here.
def archive(request):
posts = BlogPost.objects.all()
ctx = {'posts': posts}
return render(request, 'archive.html', ctx)

修改mysite/urls.py,添加访问路径。

1
2
3
4
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls')),
]

修改blog/urls.py文件,添加访问路径。

1
2
3
urlpatterns = [
url(r'^blog/', 'blog.views.archive'),
]

好了,可以访问了,输入网址http://localhost:8000/blog/

开始