目录
  1. 1. 安装
  2. 2. 开始项目
    1. 2.1. 创建项目
    2. 2.2. 启动开发Web服务器
  3. 3. 视图——View & URLconf
    1. 3.1. 视图
    2. 3.2. URLconf
    3. 3.3. Django处理请求过程
  4. 4. 模板——template
    1. 4.1. 完整Django开发流程
    2. 4.2. 模板继承
  5. 5. 模型
    1. 5.1. 创建app
    2. 5.2. Django配置MySQL数据库
    3. 5.3. 编写数据库模型
    4. 5.4. 安装&测试模型
      1. 5.4.1. 安装模型
      2. 5.4.2. 检查模型有效性
    5. 5.5. 执行模型
    6. 5.6. 插入数据
  6. 6. Django admin管理站点
  7. 7. 表单
    1. 7.1. 获取request对象数据
    2. 7.2. HTTP Header信息
      1. 7.2.1. 利用模板列出所有HTTP Header信息实例
    3. 7.3. 获取表单提交的数据
      1. 7.3.1. 实例一
      2. 7.3.2. 实例二

 最近在整理之前的笔记,这是之前自学Django时记录的,梳理以备查阅。教程看的是The Django Book中文版

安装

 基本环境

  • Ubuntu14.04 LTS
  • Django1.7.1
  • Python2.7.6
1
$> pip install Django==1.7.1

开始项目

创建项目

1
2
3
4
5
6
7
8
9
10
$> django-admin.py startproject mysite(项目名)  

新建目录结构
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
  • init.py :让 Python 把该目录当成一个开发包 (即一组模块)所需的文件。 这是一个空文件,一般你不需要修改它。
  • manage.py :一种命令行工具,允许你以多种方式与该 Django 项目进行交互。 键入python manage.py help,看一下它能做什么。 你应当不需要编辑这个文件;在这个目录下生成它纯是为了方便
  • settings.py :该 Django 项目的设置或配置。 查看并理解这个文件中可用的设置类型及其默认值。

    1
    2
    3
    #修改配置项:
    LANGUAGE_CODE = 'zh-cn'
    TIME_ZONE = 'Asia/Shanghai'
  • urls.py:Django项目的URL设置。 可视其为你的django网站的目录。 目前,它是空的。

  • wsgi.py:Django工程入口

启动开发Web服务器

1
2
3
4
5
#首次启动先执行
$> python manage.py migrate

#启动Web服务器
$> python manage.py runserver ip:port

视图——View & URLconf

视图

 创建视图文件:mysite/mysite/views.py

1
2
3
4
5
from django.http import HttpResponse

#视图函数
def hello(request):
return HttpResponse("Hello world")

 每个视图函数至少要有一个参数,通常被叫作request。 这是一个触发这个视图、包含当前Web请求信息的对象,是类django.http.HttpRequest的一个实例。在这个示例中,我们虽然不用request做任何事情,然而它仍必须是这个视图的第一个参数。

URLconf

 URLconf是为了绑定视图函数和URL,当使用django-admin.py startproject创建项目时,该脚本会自动创建一份 URLconf(即urls.py)
 在添加URLconf前,需要告知Django URLconf的根目录路径。mysite/settings.py中添加ROOT_URLCONF = 'mysite.urls'

1
2
3
4
5
6
from django.conf.urls.defaults import *
from mysite.views import hello #import视图函数

urlpatterns = patterns('',
('^hello/$', hello),
)

Django处理请求过程

  • 进来的请求转入/hello/
  • Django通过mysite/settings.py里的ROOT_URLCONF配置来决定根URLconf.
  • Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。
  • 如果找到匹配,将调用相应的视图函数(mysite/views.py里的函数)
  • 视图函数返回一个HttpResponse
  • Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来(带有HTTP头和body的Web Response)

模板——template

 模板是Django中页面展示部分,包含HTML/CSS/JS等内容。
 在mysite/settings.py中指定模板路径

1
2
3
4
5
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)

完整Django开发流程

  • 编写模板文件
     在项目文件夹下创建模板文件夹:mysite/templates

    1
    2
    3
    4
    5
    <html>
    <body>
    It is now {{nowTime}}.
    </body>
    </html>

  • 创建视图函数
     在mysite/views.py中创建视图函数。此为最基础的方法

    1
    2
    3
    4
    5
    6
    7
    8
    from django.template.loader import get_template
    from django.template import Context

    def hourTemplate(request):
    now = datetime.datetime.now()
    temp = get_template('hourTemplate.html') #创建template对象
    html = temp.render(Context({'nowTime': now})) #创建Context和调用render()方法
    return HttpResponse(html)
  • 快捷调用模板:render_to_response
     在视图函数中可以使用快捷调用模板的函数render_to_response,此方法较为常用。

    1
    2
    3
    4
    from django.shortcuts import render_to_response
    def hourTemplate(request):
    now = datetime.datetime.now()
    return render_to_response('hourTemplate.html', {'nowTime': now})
  • 设置URL
     在mysite/urls.py中添加URLconf

    1
    2
    3
    4
    5
    from mysite.views import hourTemplate
    urlpatterns = patterns(
    '',
    (r'^hourTemplate/$', hourTemplate),

模板继承

 模板还能使用标签(if/elseforifequal/ifnotequal),具体详见The Django Book 第四章
 模板还有一个非常重要的功能:模板继承,为了减少共用页面所引起的重复和冗余代码,Django解决此问题的首选方法是使用模板继承。下面通过一个实例加以说明。
 模板目录下有三个模板文件templates/base.html、now.html、later.html

  • base.html——基础模板,每个block name必须唯一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
    <div align='center'>
    <h1 id="content1">Template Inherit</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thank for visitting my website</p>
    {% endblock %}
    </div>
    </body>
    </html>

  • now.html

    1
    2
    3
    4
    5
    6
    {% extends 'base.html' %}

    {% block title %}This is now.html{% endblock %}
    {% block content %}
    <p>Now time is {{ nowTime }} </p>
    {% endblock %}

  • later.html

    1
    2
    3
    4
    5
    6
    {% extends 'base.html' %}

    {% block title %}This is later.html{% endblock %}
    {% block content %}
    <p>In {{ hours }} hour(s) later, it will be {{ laterTime }} </p>
    {% endblock %}

  • 视图函数——mysite/views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import datetime
    from django.http import Http404
    from django.shortcuts import render_to_response

    def now(request):
    """template inherit now"""
    now = datetime.datetime.now()
    return render_to_response('now.html', {'nowTime': now})

    def later(request, hourNum):
    """template inherit later"""
    try:
    hours = int(hourNum)
    except Exception, e:
    return Http404, e
    hourLater = datetime.datetime.now() + datetime.timedelta(hours=hours)
    return render_to_response('later.html', {'hours': hours, 'laterTime': hourLater})
  • URLconf配置

    1
    2
    3
    4
    urlpatterns = patterns('', 
    url(r'^now/$', now),
    url(r'^later/(\d{1,2})/$', later),
    )

模型

 Django若需要与数据库交互则使用模型Model。模型负责数据库层面,app才可使用模型,project不行,所以需要先创建app。

创建app

1
2
3
4
5
6
7
8
9
10
11
$> python manage.py startapp appname

app目录结构:
books/
models.py
migrations/
__init__.py
views.py
admin.py
__init__.py
tests.py

Django配置MySQL数据库

mysite/setting.py(NAME中的数据库需要预先创建)

1
2
3
4
5
6
7
8
9
10
DATABASES = { 
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books',
'USER': 'root',
'PASSWORD': 'moguoliang',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}

 测试Django连接数据库

1
2
3
$> python manage.py shell
from django.db import connection
cursor = connection.cursor()

编写数据库模型

mysite/books/models.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.db import models

class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=30)
website = models.URLField()


class Author(models.Model):
firstName = models.CharField(max_length=30)
lastName = models.CharField(max_length=40)
email = models.EmailField(blank=True,verbose_name='e-mail') #允许空白


class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publicationDate = models.DateField(blank=Ture, null=True)

安装&测试模型

安装模型

mysite/setting.py

1
2
3
INSTALLED_APPS = (
'books',
)

检查模型有效性

1
2
3
$> python manage.py check        

#python manage.py validate #旧版本

执行模型

models.py变更后都要执行makemigrationsmigratesqlmigrate仅用来查看SQL语句

1
2
3
4
5
6
7
8
# 生成migrate
$> python manage.py makemigrations books
#查看SQL语句
$> python manage.py sqlmigrate books 0001
#执行SQL语句
$> python manage.py migrate

#python manage.py syncdb #旧版本

插入数据

 使用Django提供的Python Shell进行插入数据测试。插入数据有两种方法:1. 逐条插入数据;2. 批量插入数据

  • 逐条插入

    1
    2
    3
    4
    5
    $> python manage.py shell

    >>> from book.models import Publisher
    >>> p1 = Publisher(name='test', address='GaoXinYuan', city='Shenzhen', state_province='Guangdong', country='China', website='http://10.0.2.15:8000')
    >>> p1.save()
  • 批量插入——objects.create()

    1
    2
    3
    4
    5
    6
    $> python manage.py shell
    >>> from book.models import Publisher
    >>> p1 = Publisher.objects.create(name='Apress', ... address='2855 Telegraph Avenue', ... city='Berkeley', state_province='CA', country='U.S.A.', ... website='http://www.apress.com/')
    >>> p2 = Publisher.objects.create(name="O'Reilly", ... address='10 Fawcett St.', city='Cambridge', ... state_province='MA', country='U.S.A.', ... website='http://www.oreilly.com/')
    >>> publisher_list = Publisher.objects.all()
    >>> publisher_list
  • 操作数据库的常用函数方法

    • Plulisher.objects.create() 插入数据
    • Publisher.objects.all() 显示所有数据
    • Publisher.objects.filter(name=’Apress’) 过滤显示数据
    • Publisher.objects.get(name=”Apress”) 获取单个对象
    • Publisher.objects.order_by(“name”) 数据排序
    • Publisher.objects.order_by(“-name”) 逆向数据排序
    • Publisher.objects.filter(country=”U.S.A.”).order_by(“-name”) 连锁查询
    • Publisher.objects.order_by(‘name’)[0] 限制返回数据(limit 1)
    • Publisher.objects.filter(id=52).update(name=’Apress Publishing’) 更新数据
    • Publisher.objects.filter(country=’USA’).delete() 删除数据

Django admin管理站点

  • 创建管理员用户

    1
    $> python manage.py createsuperuser
  • 重置superuser密码

    1
    $> python manage.py changepassword username
  • 检查mysite/urls.py

    1
    url(r'^admin/', include(admin.site.urls)),
  • 将模型model添加进admin管理——mysite/book/admin.py

    1
    2
    3
    4
    5
    6
    from django.contrib import admin
    from book.models import Publisher, Author, Book
    # Register your models here.
    admin.site.register(Publisher)
    admin.site.register(Author)
    admin.site.register(Book)

表单

获取request对象数据

 视图函数hello(request)中的第一个参数是一个HttpRequest对象,我们可以通过此对象获取一些有用信息。

1
2
3
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello world")

 HttpRequest对象包含当前请求URL的一些信息:

  • request.path:除域名以外的请求路径,以正斜杠开头。例如:”/hello/“
  • request.get_host():主机名(比如,通常所说的域名)。 例如:”127.0.0.1:8000” or “www.example.com"
  • request.get_full_path():请求路径,可能包含查询字符串。例如:”/hello/?print=true”
  • request.is_secure():如果通过HTTPS访问,则此方法返回True; 否则返回False。

HTTP Header信息

request.META是一个Python字典,包含了所有本次HTTP请求的Header信息
 利用request.META获取HTTP Header信息:

1
2
3
def ua_display_good2(request):
ua = request.META.get('HTTP_USER_AGENT', 'unknown')
return HttpResponse("Your browser is %s" % ua)

利用模板列出所有HTTP Header信息实例

  • 创建模板——mysite/templates/displayHeaderTemp.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <html> 
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>{% block title %}{% endblock %}</title>
    <body>
    <ul>
    {% for tkey, tvalue in headDict.iteritems %}
    <li>{{tkey}}: {{tvalue}}</li>
    {% endfor %}
    </ul>
    </body>
    </head>
    </html>

  • 添加视图函数——mysite/views.py

    1
    2
    3
    4
    from django.shortcuts import render_to_response

    def displayHeaderTemp(request):
    return render_to_response('displayHeaderTemp.html', {'title': 'displayHeaderTemplate', 'headDict': request.META})
  • 配置URL——mysite/urls.py

    1
    2
    3
    4
    from mysite.views import displayHeaderTemp
    urlpatterns = patterns(
    url(r'^displayHeaderTemp/$', displayHeaderTemp),
    )

获取表单提交的数据

  • request.GET:获取用户通过GET方法提交的表单数据(参数URL中可见)
  • request.POST:获取用户通过POST方法提交的表单数据

实例一

 用户通过searchForm页面GET方法提交表单数据,跳转到search页面,通过request.GET获取用户提交数据并在页面显示

  • 创建模板——templates/searchForm.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <html> 
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>search form</title>
    </head>
    <body>
    <form action="/search/" method="get" accept-charset="utf-8">
    <input type="text" name="q" value="">
    <input type="submit" value="Search &rarr;">
    </form>
    </body>
    </html>
  • 创建视图——books/views.py
    books/views.py是在books这个app里的视图,非mysite/views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from django.shortcuts import render, render_to_response
    from django.http import HttpResponse

    def searchForm(request):
    return render_to_response('searchForm.html')

    def search(request):
    if 'q' in request.GET:
    message = "You search for: %s" % request.GET['q']
    else:
    message = "You sumit an empty form."
    return HttpResponse(message)
  • 配置URL——mysite/urls.py
     因为searchForm会跳转到search,url配置中必须有search及相对于的视图函数

    1
    2
    3
    4
    5
    from books import views
    urlpatterns = patterns('',
    url(r'^searchForm/', views.searchForm),
    url(r'^search/', views.search),
    )

实例二

 利用Django提交表单发送邮件

  • 邮件设置——mysite/setting.py

    1
    2
    3
    4
    5
    6
    7
    8
    #email setting
    #EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_HOST = 'smtp.163.com'
    EMAIL_PORT = 25
    EMAIL_HOST_USER = 'xxxxx@163.com'
    EMAIL_HOST_PASSWORD = '**********'
    EMAIL_USE_TLS = True
    #EMAIL_SUBJECT_PREFIX = u'Django邮件测试'
  • 测试利用Django发送邮件
     返回1则成功,0则失败

    1
    2
    3
    $> python manage.py shell
    >>> from django.core.mail import send_mail
    >>> send_mail('DjangoMail','test','autodeploy@163.com', ['221bmogl@gmail.com'], fail_silently=True)

    send_mail()函数参数解释:

    • send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None,auth_password=None, connection=None)
    • subject, message, from_email and recipient_list 这四个参数是必须的。

    • subject: 字符串,表示邮件标题。

    • message: 字符串,表示邮件内容。
    • from_email: 字符串,表示发件邮箱。
    • recipient_list: 字符串列表,列表中每个成员都是一个邮箱地址,而且每个收件人都会在 “收件人/To:” 栏看到出现在 recipient_list 中的其他收件人。
    • fail_silently: (可选)布尔值。为 False 时, send_mail 会抛出 smtplib.SMTPException 异常。 smtplib 文档列出了所有可能的异常。 这些异常都是 SMTPException 的子类。
    • auth_user: (可选)SMTP服务器的认证用户名。没提供该参数的情况下,Django会使用 EMAIL_HOST_USER 配置项的设置。
    • auth_password: (可选)SMTP服务器的认证密码,没提供该参数的情况下,Django会使用EMAIL_HOST_PASSWORD 配置项的设置。
    • connection: (可选)发送邮件的后端。没提供该参数的情况下,Django会使用默认后端的实例。可查看 Email backends 了解更多细节。
  • 创建模板——templates/contactForm.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Contact us</title>
    </head>
    <body>
    <h1 id="content1">Contact us</h1>
    {% if error %}
    <ul>
    {% for eachError in error %}
    <li> {{eachError}}</li>
    {% endfor %}
    </ul>
    {% endif %}
    <form action="" method="post" accept-charset="utf-8">
    <!-- 此处需要{% csrf_token %}、不然会CSRF验证失败! -->
    <span style="color: #ff0000;">{% csrf_token %}</span>
    <p>Subject: <input type="text" name="subject" value="{{subject}}"></p>
    <p>Your e-mail(optional): <input type="text" name="email" value="{{email}}"></p>
    <p>Message: <textarea name="message" rows="8" cols="40">{{message}}</textarea></p>
    <p><input type="submit" value="Continue &rarr;"></p>
    </form>
    </body>
    </html>

  • 创建视图函数——mysite/views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    def contact(request):
    error = []
    if request.method == 'POST':
    if not request.POST.get('subject'):
    error.append('Enter a subject')
    if not request.POST.get('message'):
    error.append('Enter a message')
    if request.POST.get('email') and '@' not in request.POST['email']:
    error.append('Enter a valid email address:')
    if not error:
    emailMessage = ': '.join([request.POST.get('email', 'UserEmailEmpty'), request.POST['message']])
    send_mail(
    request.POST['subject'],
    emailMessage,
    'xxxxx@163.com',
    ['fatesai@gmail.com'],
    fail_silently=True,
    )
    #return HttpResponseRedirect('/contact/thanks/', RequestContext(request))
    return HttpResponseRedirect('/contact/thanks/')
    return render_to_response('contactForm.html', RequestContext(request, {'error': error}))
  • URL设置——mysite/urls.py

    1
    2
    3
    4
    5
    from mysite.views import contact, thanks
    urlpatterns = patterns('',
    url(r'^contactus/', contact),
    url(r'^contact/thanks/', thanks)
    )

Powered: Hexo, Theme: Nadya remastered from NadyMain