Django入门笔记



看的Django 1.8.2 中文文档,地址:http://python.usyiyi.cn/django_182/intro/tutorial01.html ,想学习的直接看这个文档吧。这篇文章全是摘的中文文档的内容的。


1. 创建一个项目
在命令行中,进入你要用来保存代码的目录,然后输入如下命令:
$ django-admin startproject mysite
此时该目录下会生成一个mysite目录。目录结构为:
mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

这些文件是:

  • 外层的mysite/根目录仅仅是项目的一个容器。它的命名对Django无关紧要;你可以把它重新命名为任何你喜欢的名字。
  • manage.py:一个命令行工具,可以使你用多种方式对Django项目进行交互。
  • 内层的mysite/目录是你的项目的真正的Python包。它是你导入任何东西时将需要使用的Python包的名字(例如 mysite.urls)。
  • mysite/__init__.py:一个空文件,它告诉Python这个目录应该被看做一个Python包。 
  • mysite/settings.py:该Django 项目的设置/配置。
  • mysite/urls.py:该Django项目的URL声明;你的Django站点的“目录”。
  • mysite/wsgi.py:用于你的项目的与WSGI兼容的Web服务器入口
2. 建立数据库
运行如下命令来在数据库中创建表(默认的是sqlite)。
$ python manage.py migrate
migrate查看INSTALLED_APPS设置并根据mysite/settings.py文件中的数据库设置创建任何必要的数据库表,数据库的迁移还会跟踪应用的变化。 你会看到对每次迁移有一条信息。

3. 运行Your Project:

mysite目录下,运行以下命令:

$ python manage.py runserver

你将看到命令行下输出了以下内容:

Performing system checks...

0 errors found
May 13, 2015 - 15:50:53
Django version 1.8, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
此时可以在浏览器中访问 http://127.0.0.1:8000/。 在淡蓝色背景下,你将看到一个“Welcome to Django”的页面。  它运行成功了!

默认情况下, runserver 命令在内部IP的8000端口启动开发服务器。当然你也可以修改端口以及IP如
$ python manage.py runserver 8080 # 修改端口为8080
$ python manage.py runserver 0.0.0.0:8000 # 修改IP和端口,当IP为0.0.0.0时,可以监听任意的网络接口
4. 创建应用
现在项目已经建立了,你可以在项目中创建App(应用能够完成一个具体的任务)。

在与manage.py相同的目录下,并且键入以下命令来创建你的应用: 

$ python manage.py startapp polls

这将创建一个目录polls,它的结构如下:

polls/
    __init__.py
    admin.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py
5. 创建Models
模型对应着数据库中表和相关访问操作。

比如我们编辑polls/models.py文件,并让它看起来像这样:

polls/models.py
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

上述代码非常直观。每个模型都用一个类表示,该类继承自django.db.models.Model每个模型都有多个类变量,而每一个类变量又都代表了数据库表中的一个字段。

每个字段通过Field类的一个实例表示 —— 例如字符字段CharField和日期字段DateTimeField这种方法告诉Django,每个字段中保存着什么类型的数据。Django支持所有常见的数据库关联:多对一、多对多和一对一。

有了上面的代码,Django在polls应用激活(安装)时就可以:

  • 为该应用创建数据库表(CREATE TABLE 语句)。
  • Question对象和Choice对象创建一个访问数据库的python API。

6. 激活应用
我们创建了polls应用,应该要告诉mysite,我们创建了它。

编辑mysite/settings.py文件,并修改INSTALLED_APPS设置以包含字符串'polls'所以它现在是这样的:

mysite/settings.py
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
)

现在Django知道要包含polls应用。 让我们运行另外一个命令:

$ python manage.py makemigrations polls

你应该看到类似下面的内容:

Migrations for 'polls':
  0001_initial.py:
    - Create model Question
    - Create model Choice
    - Add field question to choice

通过运行makemigrations告诉Django,已经对模型做了一些更改(在这个例子中,你创建了一个新的模型)并且会将这些更改存储为迁移文件Django使用迁移文件来保存对模型的更改(即数据库模式的更改)—— 所谓迁移文件其实就是磁盘上的普通文件。 


sqlmigrate命令接收迁移文件的名字并返回它们的SQL语句:

$ python manage.py sqlmigrate polls 0001

你应该会看到类似如下的内容(为了便于阅读我们对它重新编排了格式):

BEGIN;
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;

COMMIT;

请注意以下几点:

  • 输出的具体内容会依据你使用的数据库而不同。 以上例子使用的数据库是PostgreSQL。
  • 表名是自动生成的,由app的名字(polls)和模型名字的小写字母组合而成 —— questionchoice(你可以重写这个行为。)
  • 主键(IDs)是自动添加的。 (你也可以重写这个行为。)
  • 按照惯例,Django会在外键的字段名后面添加 "_id"。(是的,你依然可以重写这个行为。)
  • 外键关系由FOREIGN KEY约束显式声明。不用在意DEFERRABLE部分;它只是告诉PostgreSQL直到事务的最后再执行外键关联。
  • 这些SQL语句是针对你所使用的数据库定制的,所以会为你自动处理某些数据库所特有的字段例如auto_increment (MySQL)、serial (PostgreSQL)或integer primary key autoincrement (SQLite) 。在处理字段名的引号时也是如此 —— 例如,使用双引号还是单引号。
  • sqlmigrate命令并不会在你的数据库上真正运行迁移文件 —— 它只是把Django 认为需要的SQL打印在屏幕上以让你能够看到。 这对于检查Django将要进行的数据库操作或者你的数据库管理员需要这些SQL脚本是非常有用的。

模型变更的三个步骤:

  • 修改你的模型(在models.py文件中)。
  • 运行python manage.py makemigrations ,为这些修改创建迁移文件
  • 运行python manage.py migrate ,将这些改变更新到数据库中。

7. 使用DjangoAPI

如下命令来调用Python shell:

$ python manage.py shell
8. 创建管理员用户

首先,我们需要创建一个能够登录管理站点的用户。 运行如下命令:

$ python manage.py createsuperuser

键入你想要使用的用户名,然后按下回车键:

Username: admin

然后提示你输入想要使用的邮件地址:

Email address: [email protected]

最后一步是输入你的密码。 你将被要求输入你的密码两次,第二次输入是为了确认第一次的输入。

Password: **********
Password (again): *********
Superuser created successfully.
9. 注册应用

我们需要告诉管理站点Question 对象要有一个管理界面。 要做这件事,需要打开polls/admin.py文件,把它编辑成这样:

polls/admin.py
from django.contrib import adminfrom .models import Questionadmin.site.register(Question)
10. 编辑视图

让我们来编写第一个视图。 打开polls/views.py文件并将以下Python代码写入:

polls/views.py
from django.http import HttpResponsedef index(request):return HttpResponse("Hello, world. You're at the polls index.")

这可能是Django中最简单的视图。 为了能够调用这个视图,我们需要将这个视图映射到URL上 —— 利用一个URLconf。

为了在投票应用目录内部创建URLconf,需要创建一个urls.py文件。你的应用的目录现在看起来应该像这样:

polls/
    __init__.py
    admin.py
    models.py
    tests.py
    urls.py
    views.py

polls/urls.py文件中键入如下代码:

polls/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [url(r'^$', views.index, name='index'),]

下一步,让主URLconf可以链接到polls.urls模块。mysite/urls.py中插入一个include()

mysite/urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [url(r'^polls/', include('polls.urls')),url(r'^admin/', include(admin.site.urls)),]
现在我们已经将一个index视图关联到URLconf中。 在你的浏览器中浏览 http://localhost:8000/polls/ , 你会看到 “Hello, world.  You’re at the polls index.”, 正如你在index 视图中定义的那样.

11. 创建模版

页面的设计被硬编码在视图中。 如果你想更改页面的外观,就得编辑这段Python代码。

首先,在你的polls目录下创建一个叫做 templates的目录。Django将在这里查找模板。

按照惯例,DjangoTemplates在 INSTALLED_APPS所包含的每个应用的目录下查找名为"templates"子目录。

在你刚刚创建的templates目录中,创建另外一个目录polls,并在其中创建一个文件index.html换句话讲,你的模板应该位于polls/templates/polls/index.html由于app_directories 模板加载器按照上面描述的方式工作,在Django中你可以简单地用polls/index.html引用这个模板。

将以下的代码放入模板文件:

polls/templates/polls/index.html
{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

现在让我们更新polls/views.py中的index视图来使用模板:

polls/views.py
from django.http import HttpResponse
from django.template import RequestContext, loader

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = RequestContext(request, {
        'latest_question_list': latest_question_list,
    })
    return HttpResponse(template.render(context))
或者这样使用:

重写后的index()视图:

polls/views.py
from django.shortcuts import render

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)
13. 带命名空间的URL名字

教程中的这个项目只有一个应用polls在真实的Django项目中,可能会有五个、十个、二十个或者更多的应用。 Django如何区分它们URL的名字呢? 例如,polls 应用具有一个detail 视图,相同项目中的博客应用可能也有这样一个视图。当使用模板标签{% url %}时,人们该如何做才能使得Django知道为一个URL创建哪个应用的视图?

答案是在你的主URLconf下添加命名空间。 mysite/urls.py文件中,添加命名空间将它修改成:

mysite/urls.py
from django.conf.urls import include, url
from django.contrib import admin

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

现在将你的模板polls/index.html由:

polls/templates/polls/index.html
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

修改为指向具有命名空间的详细视图:

polls/templates/polls/index.html
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

14. 使用通用视图
  1. 转换URLconf。
  2. 删除一些旧的、不再需要的代码。
  3. 引进基于Django通用视图的新视图。

改良URLconf 

首先,打开polls/urls.py 这个URLconf 并将它修改成:

polls/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

改良视图

下一步,我们将删除旧的indexdetail和 results 视图,并用Django的通用视图代替。打开polls/views.py文件,并将它修改成:

polls/views.py
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views import generic

from .models import Choice, Question


class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        return Question.objects.order_by('-pub_date')[:5]


class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'


class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'


def vote(request, question_id):
    ... # same as above

我们在这里使用两个通用视图:ListView 和 DetailView这两个视图分别抽象“显示一个对象列表”和“显示一个特定类型对象的详细信息页面”这两种概念。

  • 每个通用视图需要知道它将作用于哪个模型。 这由model 属性提供。
  • DetailView期望从URL中捕获名为"pk"的主键值,所以我们为通用视图把question_id改成pk 。

默认情况下,通用视图DetailView 使用一个叫做<app name>/<model name>_detail.html的模板。在我们的例子中,它将使用"polls/question_detail.html"模板。template_name属性是用来告诉Django使用一个指定的模板名字,而不是自动生成的默认名字。 我们也为results列表视图指定了template_name —— 这确保results视图和detail视图在渲染时具有不同的外观,即使它们在后台都是同一个 DetailView

你可能感兴趣的:(django,python)