Django的第一步(第二节)

写下你的第一个Django应用,第二节

第一节学习过后,我们进行第二节的学习.我们将会设置数据库,创建你的第一个模型,然后快速地讲解django自动生成的管理网站.

设置数据库

    现在,打开mysite/setting.py.这是一个普通的python模块,用于django的设置.

    django会默认使用SQLite.如果你才开始接触数据库,或者你只是有兴趣尝试使用django,SQLite是最简单的数据库.Python中包含SQLite,所以我们不需要安装任何东西用于支持你的数据库设置.然而,当你开始你第一个真正的项目时,你可能会像使用更具有扩展性的数据库,比如像是PostgreSQL,来避免数据库切换导致的头痛.

    如果你希望使用其他数据库,安装合适的数据库并且改变DATABASES'default'中的键值来匹配你的数据库连接:

  • ENGINE-------'django.db.backends.sqlite3','django.db.backends.postgresql','django.db.backends.mysql'或'django.db.backends.oracle'.其他后端也可以使用
  • NAME-------数据库的名字.如果你使用SQLite,这个数据库会以文件形式保存在你的电脑上,在这种情况下,NAME应该使用绝对路径,包括文件名.作为默认,os.path.join(BASE_DIR,'db.sqlite3'),将会保存文件在项目目录中.

    如果你没有使用SQLite作为你的数据库,USER,PASSWORD,HOST这些额外的设置需要添加.


  对于SQLite以外的数据库

    如果你使用SQLite以外的数据库,通过下面这一点确保你已经创建了一个数据库.在你的数据库交互提示符中输入"CREATE DATABASE database_name"

    同样确保mysite/setting.py中的用户有创建数据库的权限.

    如果你使用SQLite,不需要先创建任何内容,数据库文件将会自动创建.


    当你修改mysite/setting.py,设置TIME_ZONE修改你的时区.

    同样,注意文件顶部的INSTALLED_APPS设置.包含所有的在django实例中创建的应用.应用能被使用在各种项目中,你可以打包并且分发给其他人来使用.

    INSTALLED_APPS默认包含下列应用,django内部都会提供这些应用:

  • django.contrib.admin -- 管理网站,可以很快的使用
  • django.contrib.auth -- 用户认证系统
  • django.contrib.contenttypes -- 内容类型框架
  • django.contrib.sessions -- 会话框架
  • django.contrib.messages -- 消息框架
  • django.contrib.staticfiles -- 管理静态文件框架

    这些应用默认包含在基本的项目中

    一些应用确保使用一个数据库表,因此,在我们使用这些应用之前,需要创建一些数据表在数据库中.运行下面的命令来做到这些:

python manage.py migrate

    migrate命令查看INSTALLED_APPS设置,并且根据mysite/setting.py中的数据库设置和默认应用需要的数据库迁移(稍后介绍数据库迁移)来创建必须的数据库表.你会看到每一条迁移的信息.如果你感兴趣,运行数据库命令行,来显示Django创建的表 (dt(PostgreSQL) SHOW TABLES(MySQL) .schema(SQLite) SELECT TABLE_NAME FROM USER_TABLES;(Oracle))

    
  极简主义者

    就像我上面说的,这些默认的应用已经包含在程序中,但是不是每个人都需要它们.如果你不需要它们,请在运行migrate之前把他们从INSTALLED_APPS中删除.migrate命令只会对INSTALLED_APPS中的应用进行迁移.

---------------------------------------------------------------------------------------------------------------------

创建模型

    现在,我们定义你的模型,实质上是定义你的数据库布局以及其他元数据.

    在我们简单的poll应用中,我们创建了两个模型:Question和Choice,一个Question应用包含一个问题和一个创建时间.一个Choice应用包含两个文件:选择的文本和一个票数.每个Choice都与一个Question相关联.

    这些概念使用python的类来表示.编辑polls/models.py文件像下面这样:

from django.db import models

# Create your models here.
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,on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)    

    这些代码很简单.每一个模型表示着一个django.db.models.Model的子类.每一个模型拥有很多类变量,每一个变量代表数据库模型中的一个语句.

    每一个字段由一个Field类实现 -- 举个例子,CharField类用于字符字段,DateTimeField类用于日期时间.这些类告诉Django每一个字段拥有什么类型的数据.

     每一个Field实例的名称(例如question_text或pub_date)是机器友好的格式.你将会在python代码中使用这个值,并且数据库将会使用名称作为行的名称.

    一些Field类有必要的属性.CharField类就需要给一个max_length.这不仅在数据库模式中存在,在验证中使用,下面很快就能看到.    

    一个Field可以拥有各种可选的属性;比如,我们给votes设置了default为0.

    最终,使用ForeignKey来注释一个关系被定义了.这告诉Django每一个Choice都会关联一个独立的Question.Django支持所有的常见的数据库关系:多对一,多对多,一对一.

---------------------------------------------------------------------------------------------------------------------

激活模型

    这些简单地模型代码带给Django很多信息.因为它,Django可以做:

  • 创建一个数据表(CREATE DATABASE 表名)为这个应用    
  • 创建一个Python与数据库连接的接口为了连接QuestionChoice项目

    首先,我们需要告诉我们的项目polls应用已经被安装

  

  科普

    Django的应用是"可拔插"的:你可以使用一个应用在多个项目中,并且可以分发给应用程序,因为他们不必绑定到给定的Django中


    为了给项目中添加应用,我们需要在INSTALLED_APPS设置中添加一个对应用的配置.PollsConfig类在polls/apps.py中,所以它的点路径是'polls.app.PollsConfig'.编辑mysite/setting.py文件,添加点路径到INSTALLED_APPS设置中.像下面这样:

mysite/setting.py
INSTALLED_APPS = [
    'polls.app.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

    现在Django知道polls应用了.让我们运行下面的命令:

python manage.py makemigrations polls

    你应该看到与先面类似的输出:    

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

    通过运行makemigrations命令,你告诉Django你对模型做了一些改变(这时,你创建了一个新的模型)然后你想要为更改的数据进行迁移.

    迁移是Django如果存储模型的修改(以及数据库模式)--这些都只是磁盘上的文件.如果你想,你可以读取新模型的迁移数据;这些数据在polls/migrations/0001_initial.py中.不要担心,Django每次创建时不会读取他们,但是他们的设计是为了可以人为编辑,以防你想想要手动调整Django用来修改.

    有一个命令可以为你运行迁移并且自动管理你的数据库模型-这就是所谓的迁移,我们马上会说到这个.但首先,我们来看看迁移过程中的SQL命令,sqlmigrate命令后加上迁移名称会返回它们的SQL.  

python manage.py sqlmigrate polls 0001 
    你应该可以看到类似下面的输出:
BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
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数据库的输出.
  • 表的名字自动设置成应用(polls)和模型的小写名称(question和choice)的组合.(你可以覆盖这个行为)
  • 主键也是自动添加的.(你同样可以覆盖这个行为)
  • 默认的,Django添加"_id"给外键的名称(你可以覆盖这个)
  • 外键关系通过FOREIGN KEY约束来显式化.不用担心关于DEFERRABLE的部分,这只是告诉PostgreSQL在事务结束之前不执行外键。
  • sqlmigrate命令实际上不会在数据库上运行迁移 - 它只是将它打印到屏幕上,以便你可以看到SQL Django认为需要什么。这对于检查Django将要做什么或者如果你有需要SQL脚本进行更改的数据库管理员很有用。

    如果你感兴趣,你可以使用python manage.py check命令;这个命令无需使用数据库迁移或者改变数据库来检查关于你的项目的问题.

    现在,运行migrate命令再一次创建这些模型的数据表在你的数据库中:

python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK
    migrate命令做了所有的数据迁移对于那些还没有被应用的应用(Django使用名为django_migrations的数据库中的特殊表跟踪哪些是应用)然后根据数据库运行他们 - 实质上,将你对模型的更改与数据库中的模式同步.

    

    迁移非常有效并且允许你修改你的模型随时,随着你的项目完善,不需要去删除你的数据库或者数据表然后创建新的 - 迁移专门用于提升你的数据库,不用丢失数据.我们将会在后面的章节深入介绍它,不是现在,记住下面三步用于修改模型:

  • 修改你的模型(在models.py)
  • 运行python manage.py makemigrations 来为修改创建迁移.
  • 运行python manage.py migrate 来应用修改于数据库.

    单步命令执行生成和应用迁移的原因是因为你将会提交迁移到你的版本控制系统和转发他们用你的应用;单步不仅让你更好地开发,对于其他的开发者也是很有用的.

    阅读django-admin documentation查询manage.py操作的完整的信息

---------------------------------------------------------------------------------------------------------------------

调用API

    现在,让我们进入与python shell互动的环节,使用Django提供的API.要使用python shell,请使用下面的命令:

python manage.py shell

    我们使用这个命令代替简单的“python”命令,因为manage.pyDJANGO_SETTINGS_MODULE中配置了python,让你可以直接使用.

    进入python shell,使用数据库API:

>>> from polls.models import Question, Choice   # Import the model classes we just wrote.

# 没有Question在系统里面
>>> Question.objects.all()
<QuerySet []>

# 创建一个新的Question对象
# 默认启用了对时区的支持
# Django中使用tzinfo为pub_date赋值
# 用timezone.now()代替datetime.datetime.now() 它会正确地获取时间.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# 你可以使用 save()来把对象存入数据库中
>>> q.save()

# 现在,它有一个ID
>>> q.id
1

# 通过python属性访问模型字段值
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# 通过改变属性的值修改模型字段,并用save()储存.
>>> q.question_text = "What's up?"
>>> q.save()

# objects.all() 显示数据库中所有的questions对象.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

稍等一下.  <Question: Question object (1)>不是一个具有表现力的形式让我们通过修改Question模型

(在polls/model.py),QuestionChoice添加一个__str__()方法: 

polls/models.py
from django.db import models


class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text


class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text
    在你的模型中添加__str__()方法是非常重要的,不仅是为了你在与模型的互动比较方便,还因为通过Django的自动管理更容易表示.

    注意下面普通的python方法,让我们添加一个自定义方法用来演示:

polls/models.py
import datetime


from django.db import models
from django.utils import timezone




class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)    

    注意添加了import datetime from django.utils import timezone,分别python自带的标准库datetime模块和django中的django.utils.timezone,如果你对于python中对时间时区的处理,你可以查阅time zone support docs.

    保存更改并且开启一个新的python shell通过python manage.py shell:

>>> from polls.models import Question, Choice

# 确保 __str__()在工作 
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django提供了一个丰富的可以由关键字参数查找数据库的API
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# 获取时间是今年的question
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# 请求一个不存在的ID,这里会返回错误.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# 通过主键查找是最常见的情况,所以django提供了一个根据主键精确查找的方法
# 下面的结果于Question.objects.get(id=1)相同.
>>> Question.objects.get(pk=1)
<Question: What's up?>

# 确保我们自定义方法就效.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# 给予Question几个选择.创建一个新的Choice对象,使用INSERT语句,添加在choice集合当中,然后返回新的
# choice对象.Django为外键关系创建了一个关系集合.(例如:一个question's choice)可以通过API进行访
# 问.
>>> q = Question.objects.get(pk=1)

# 使用set不加参数显示任何的choices
>>> q.choice_set.all()
<QuerySet []>

# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice对象有对其相关Question对象的API访问权限.
>>> c.question
<Question: What's up?>

# 反之亦然,Question对象可以访问Choice对象.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# 如果你需要,API会自动生成关系.使用两个下划线代表属性.这个工作会更可能更多,更深地查找;没有任何限制.
# 查找所有的Choices对于所有今年的question
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# 让我们删除其中一个Choice,使用delete().
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

        你可以通过Accessing related objects. 获取更多模型关系的信息.通过Field lookups获取更多双下划线的使用用于字段查找.

---------------------------------------------------------------------------------------------------------------------

介绍Django管理员

创建一个管理员用户

    首先我们需要创建一个可以登录管理系统的用户.运行下面的命令:    

python manage.py createsuperuser

    输入你的用户名然后回车.    

Username:admin

    输入电子邮箱地址:

Email address: admin@example.com

    最后一步输入你的密码.共输入两次,第二次为确认密码.

Password: **********
Password (again): *********
Superuser created successfully.

---------------------------------------------------------------------------------------------------------------------

开始开发服务器

    Django的管理界面默认是使用的.让我们开始开发服务器并且探索它.

    如果服务器没有在运行请开启服务器:    

python manage.py runserver

    现在打开浏览器并且输入你的本地地址+'/admin/'比如http://127.0.0.1:8000/admin/.你可以看到管理登录的界面:


    因为网站的语言是默认的,所以你可以在翻译这里找到如何设置,显示自己国家的语言,如果Django支持你们国家语言的话.

---------------------------------------------------------------------------------------------------------------------

进入你的管理界面

    现在尝试登录你之前创建过的管理员帐号.你应该可以看到Django管理的索引页.


    你可以看到一些可以编辑的内容:Groups和Users.它们是由Django发布的认证框架django.contrib.auth提供的

---------------------------------------------------------------------------------------------------------------------

使管理员可以修改投票应用

    但是我们写的poll应用去哪了?这并没有显示在索引页上.

    其实只需要做一件事情就可以了:我们需要告诉Django存在Question项目即可.现在打开polls/admin.py文件然后做出如下修改:

polls/admin.py
from django.contrib import admin
from .models import Question

admin.site.register(Question)

---------------------------------------------------------------------------------------------------------------------

探索免费的管理功能

    现在我们已经注册了Question,Django会自动把它显示在索引页:

    点击"Question".现在在Question的"change list"页面.这个页面显示了所有的在数据库中的问题并且让你选择修改他们.下面我们创建一个"What's up?"question:

    点击"What's up?"question去修改它:

    注释:

  • 表单是Question模型自动生成的    
  • 不同的模型字段类型有相对应的HTML小部件.在Django管理界面中每一个字段有自己的展示.
  • 每一个DateTimeField会给予直接实用的JavaScript快捷方法.日期给予一个"Today"快捷方法和一个弹出日历,时间给予一个"Now"快捷方法和一个便捷的常用时间列表.    

    界面的底部给了一组选项:

  • 保存(Save) 保存修改并且返回到该类型修改列表界面.
  • 保存并且继续编辑(Save and continue editing) 保存并且重载该类型的修改界面
  • 保存并且添加另一个(Save and add another) 保存修改并且加载一个该对象新的空白的表单
  • 删除(Delete) 显示确认删除界面

    如果“发布日期”的值与你在教程1中创建question的时间不匹配,则可能意味着你忘记为TIME_ZONE设置正确的值.修改它,重新加载页面并检查是否显示正确的值.

    通过点击"Today"和"Now"修改"Date published".然后点击"Save and continue editing".然后点击"History"在右上角.你会看到一个包含所有管理员修改的记录,包括修改的时间和修改的人员:


    当你已经熟悉了模型的API和使用你自己的管理界面,阅读第三节来学习如何添加更多视图为我们的投票app.













原文地址:https://www.cnblogs.com/GF66/p/9785488.html