项目3 Web应用程序(第18章:Diango入门)

---恢复内容开始---

  昨天敲得忘记保存了。。。然后自动恢复了一些,有点难受。。。就当巩固一遍吧。

18.1 建立项目

18.1.1 制定规范

  编写一个名为“学习笔记”的Web应用程序,让用户能够记录感兴趣的主题,并在学习每个主题的过程中添加日志条目。“学习笔记”的主页对这个网站进行描述,并邀请用户注册或登录。用户登录后,就可以创建新主题、添加新条目以及阅读既有的条目。

18.1.2 建立虚拟环境

  要使用Django,首先需要建立一个虚拟工作环境。虚拟工作环境是系统的一个位置,你可以再其中安装包,并将其与其他Python包隔离。

  为项目新建一个目录,将其命名为learning_log,再在终端中切换到这个目录,并创建一个虚拟环境。

       

18.1.4 激活虚拟环境

  Windows系统,使用命令11_env\Scripts\activate(不包含source)

  要停止使用虚拟环境,可执行命令deactivate

18.1.5 安装Django

18.1.6 在Django中创建项目

   在仍然处于活动的虚拟环境的情况下(11_env包含在括号内),执行命令新建一个项目:

       

  这个命令末尾的句点让新项目使用合适的目录结构,千万不能忘了这个句点,否则部署应用程序时,将遭遇一些配置问题。

  目录learning_log包含4个文件,其中最重要的是settings.py、urls.py和wsgi.py。文件settings.py指定Django如何与你的系统交互以及如何管理项目。在开发项目的过程中,我们将修改其中一些设置,并添加一些设置。文件urls.py告诉Django应创建哪些网页来响应浏览器请求。文件wsgi.py帮助Django提供它创建的文件,这个文件名是web server gateway interface(Web服务器网关接口)

18.1.7 创建数据库

  为给项目“学习笔记”创建数据库,请在处于活跃虚拟环境中的情况下执行下面的命令:

python manage.py migrate

  我们将修改数据库称为迁移数据库,首次执行命令migrate时,将让Django确保数据库与项目的当前状态匹配。在使用SQLite的新项目中首次执行这个命令时,Django将新建一个数据库。

18.1.8 查看项目

  下面核实Django是否正确地创建了项目。为此,可执行命令runserver:

python manage.py runserver

  Django通过检查确认正确地创建了项目;指出了使用的Django版本以及当前使用的设置文件的名称;它指出了项目的URL。

  Django启动一个服务器,让你能够查看系统中的项目,了解它们的工作情况。

  现打开一款Web浏览器,并输入URL:http://localhost:8000/;如果不管用,请输入http://127.0.0.1:8000/

18.2 创建应用程序

  Django项目由一系列应用程序组成,它们协同工作,让项目成为一个整体。我们暂时只创建一个应用程序,它将完成项目的大部分工作。

  当前,在前面打开的终端窗口中应该还运行着runserver。请再打开一个终端窗口(或标签页),并切换到manage.py所在的目录。激活虚拟环境,再执行命令startapp:

python manage.py startapp learning_logs

  命令startapp appname让Django建立创建应用程序所需的基础设施。项目目录增加一个文件夹learning_logs。打开这个文件夹,其中最重要的文件是models.py、admin.py和views.py。我们将使用models.py来定义我们要在应用程序中管理的数据。

18.2.1 定义模型

  打开文件models.py,下面表示用户将要存储的主题的模型:

from django.db import models

# 定义了一个名为Topic的类,它继承了Model—Django中一个定义了模型基本功能的类
# 属性text是一个CharField—由字符或文本组成的数据。需要存储少量的文本,如名称、标题或城市时,可以使用
#  date_added是一个DateTimeField—记录日期和时间的数据。
class Topic(models.Model):
    """用户学习主题"""
    text = models.CharField(max_length=200)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        """返回模型的字符串表示"""
        return self.text

  注意,要或许可在模型中使用的各种字段,请参阅Django Model Field Reference(Django模型字段参考),其网址为https://docs.djangoproject.com/en/1.8/ref/models/fields/

18.2.2 激活模型

  要使用模型,必须让Django将应用程序包含到项目中。为此,打开dettings.py,你将看到下面的片段,这是一个元组,告诉Django是由哪些元组组成的。添加learning_logs。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # My apps
    'learning_logs',
]

  接下来,需要让Django修改数据库,使其能够存储与模型Topic相关的信息。为此在终端窗口执行命令:

python manage.py makemigrations learning_logs

  输出表明Django创建了一个名为0001_initial.py的迁移文件,这个文件将在数据库中为模型Topic创建一个表。

  下面来应用这种迁移。让Django替我们修改数据库:

python manage.py migrate

  每当需要修改“学习笔记”管理的数据时,都采取如下三个步骤:修改models.py;对learning_logs调用makemigrations;让Django迁移项目。

18.2.3 Django管理网站

  为应用程序定义模型,Django提供的管理网站让你能够轻松地处理模型。网站的管理员可使用管理网站,但普通用户不能使用。

1、创建超级用户

python manage.py createsuperuser

  昨天的数据丢失啦,只能重新创建一个管理员了,密码需要数字和字母的结合,email地址可为空。

2、向管理网站注册模型

  Django自动在管理网站中添加了一些模型,如User和Group,但对于我们创建的模型,必须手工注册。

  打开admin.py文件,为向管理网站注册Topic,请输入以下代码:

from django.contrib import admin

from learning_logs.models import Topic

admin.site.register(Topic)

  现在,使用超级用户账户访问管理网站:http://localhost:8000/admin,这个网页让你能够添加和修改用户和用户组,还可以管理与刚才定义的模型Topic相关的数据。

3、添加主题

18.2.4 定义模型Entry

  要记录学到的国际象棋和攀岩知识,需要为用户可在学习笔记中添加的条目定义模型。每个条目都与特定主题相关联,这种关系被称为多对一关系,即多个条目可关联到同一主题。

  下面是模型Entry的代码:

class Entry(models.Model):
    """学到的有关某个主题的具体知识"""
    # ForeignKey外键,引用了数据库中的另一条记录;
    # 每个主题创建时,都给它分配了一个键(或ID)。
    # 嵌套Meta类,Meta存储用于管理模型的额外信息。
    topic = models.ForeignKey(Topic,on_delete=models.CASCADE)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'entries'
    def __str__(self):
        return self.text[:50]+"..."

18.2.5 迁移模型Entry

  由于我们添加了一个新模型,因此需要再次迁移数据库。你将慢慢地对这个过程了如指掌:修改models.py,执行命令python manage.py makemigrations app_name,再执行命令python manage.py migrate。

  下面来迁移数据库并查看输出:

18.2.6 向管理网站注册Entry

from django.contrib import admin

from learning_logs.models import Topic,Entry

admin.site.register(Topic)
admin.site.register(Entry)

  返回到http://localhost:8000/admin/(注意需要重新开启服务器)

  下面添加条目:

18.2.7 Django shell

  输入一些数据,就可以通过交互终端会话以编程方式查看这些数据了。这种交互式环境称为Django shell,是测试项目和排除其他故障的理想之地。  

      

  返回一个列表,称为查询集(queryset)

  下面演示了如何查看分配给每个主题对象的ID:

     

  知道对象的ID后,就可获取该对象并查看其任何属性。下面来看看主题Chess的属性text和date_added的值:

     

  我们还可以查看与主题相关联的条目。前面我们给模型Entry定义了属性topic,这是一个ForeignKey,将条目与主题关联起来。利用这种关联,Django能够获取与特定主题相关联的所有条目:

       

  为通过外键关系获取数据,可使用相关模型的小写名称、下划线和单词set。

  注意,每次修改模型后,你都需要重启shell,这样才能看到修改的效果。如果想要退出shell会话,Windows系统可以按ctrl+Z,再按回车键。

  p369 18-2简短的条目,使得50字以内不显示省略号。

    class Meta:
        verbose_name_plural = 'entries'
    def __str__(self):
        if (len(self.text))>50:
            return self.text[:50]+"..."
        else:
            return self.text

  

18.3 创建网页:学习笔记主页

   使用Django创建网页的过程通常分三个阶段:定义URL、编写视图和编写模块。首先,你必须定义URL模式。URL模式描述了URL是如何设计的,让Django知道如何将浏览器请求于网站URL匹配,以确定返回哪个网页。

  每个URL都被映射到特定的视图——视图函数获取并处理网页所需的数据。视图通常调用一个模板,后者生成浏览器能够理解的网页。

18.3.1 映射URL

  当前,基础URL(http://localhost:8000/)返回默认的Django网站,让我们知道正确地建立了项目。我们将修改这一点,将这个基础URL映射带“学习笔记”主页。

  打开项目主文件夹learning_log中的文件urls.py:

from django.conf.urls import url
from django.contrib import admin

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

  前两行导入为项目和管理网站URL的函数和模块。这个文件的主题定义了变量urlpatterns。在这个针对整个项目的urls.py文件中,变量urlpatterns包含项目中的应用程序的URL。我们需要包含learning_logs的URL:

from django.conf.urls import url
from django.contrib import admin

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

  添加了一行代码,让我们能够将learning_logs的URL同项目中的其他URL区分开来,这在项目开始扩展时很有帮助。

  默认的urls.py包含在文件夹learning_log中,现在我们需要在文件夹learning_logs中创建另一个urls.py文件:

"""定义learning_logs的URL模式"""
from django.conf.urls import url
from .import views

urlpatterns = [
    # 主页
    url(r'^$',views.index,name='index')
]

  实际的URL模式是一个对函数url()的调用,这个函数接受三个实参。第一个是一个正则表达式。r'^$',其中r让Python将接下来的字符串视为原始字符串,而引号告诉Python正则表达式始于和终于何处。脱字符(^)让Python查看字符串的开头,而美元符号让Python查看字符串的末尾。总体而言,这个正则表达式让Python查找开头和末尾之间没有任何东西的URL。url的第二个实参指定了要调用的视图函数。第三个实参将这个URL模式的名称指定为index,让我们能够在代码的其他地方引用它。

18.3.2 编写视图

  视图函数接受请求中的信息,准备好生成网页所需的数据,再将这些数据发送给浏览器。

  learning_logs中的文件views.py是你执行命令python manage.py startapp时自动生成的,当前其内容如下:

from django.shortcuts import render

# Create your views here.

  为主页编写视图:

from django.shortcuts import render

# Create your views here.
def index(request):
    """学习笔记的主页"""
    return render(request,'learning_logs/index.html')

  URL请求与我们刚才定义的模式匹配时,Django将在文件views.py中查找函数index,再将请求对象传递给这个视图函数。render()提供了两个实参:原始请求对象以及一个可用于创建网页的模板。下面来编写这个模板。

18.3.3 编写模板

  在文件夹learning_logs中新建一个文件夹,并将其命名为templates。在文件夹templates中,再创建一个文件夹,并将其命名为learning_logs,在最里面的文件夹learning_logs中,新建一个文件,并将其命名为index.html,再在这个文件中编写如下代码:

<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning,for any topic you're
learning about</p>

  现在,如果你请求这个项目的基础URL——http://localhost:8000/,将看到刚才创建的网页,而不是磨人的Django网页。

18.4 创建其他网页

  我们将创建两个显示数据的网页,其中一个列出所有的主题,另一个显示特定主题的所有条目。对于每个网页我们都将指定URL模式,编写一个视图函数,并编写一个模板。但这样做之前,先创建一个父模板,项目中的其他模板都继承它。

18.4.1 模板继承

  1、父模板

  首先创建一个名为base.html的模板,并将其存储在index.html所在目录中。这个文件包含所有页面都有的元素;其他模板都继承base.html。

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a>
</p>

{% block content %}{% endblock content %}

  这个文件的第一部分创建一个包含项目名的段落,该段落也是一个到主页的链接。为创建链接,我们使用了一个模板标签,它是用大括号和百分号表示的。

  在简单的HTML页面中,链接是使用锚标签定义的:

<a href='link_url>link text</a>

  插入了块标签,这个快名为content,是一个占位符,其中包含的信息将由子模板指定。

  2、子模板

  现在需要重新编写index.html,使其继承base.html,如下所示:

{% extends "learning_logs/base.html" %}

{% block content %}
    <p>Learning Log helps you keep track of your learning,for any topic you're
    learning about</p>
{% endblock content %}

18.4.2 显示所有主题的页面

  1、URL模式

  首先,定义显示所有主题的页面的URL。修改learning_logs/urls.py:

"""定义learning_logs的URL模式"""
from django.conf.urls import url
from .import views

urlpatterns = [
    # 主页
    url(r'^$',views.index,name='index'),
    # 显示所有的主题
    url(r'^topics/$',views.topics,name='topics'),
]

  我们只是在正则表达式中添加了topics/。Django检查请求的URL时,这个模式与这样的URL匹配:基础URL后面跟着topics。可以在末尾包含斜杠,也可以省略它,但单词topics后面不能有任何东西,否则就与该模式不匹配。其URL与该模式匹配的请求都将交给views.py中的函数topics()进行处理。

  2、视图

  函数topics()需要从数据库中获取一些数据,并将其发送给模板。我们需要在views.py中添加的代码如下:

from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
    """学习笔记的主页"""
    return render(request,'learning_logs/index.html')
def topics(request):
    """显示所有的主题"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)

  3、模板

  创建一个文件,将其命名为topics.html,并存储到index.html所在目录中。下面演示了如何在这个模块中显示主题:

{% extends "learning_logs/base.html" %}

{% block content %}
    <p>Topics</p>
    <ul>
        {% for topic in topics %}
            <li>{{topic}}</li>
        {% empty %}}
            <li>No topics have been added yet.</li>
        {% endfor %}
    </ul>
{% endblock content %}

  这个网页的主体是一个项目列表,其中列出了用户输入的主题。在标准HTML中,项目列表被称为无序列表,用标签<ul></ul>表示。

  在模块中,每个for循环都必须使用{% endfor %}标签来显示地指出其结束的位置。因此在模块中,循环类似于下面这样:

{% for item in list %}
       do something witn each item
{% endfor %}

  现在需要修改父模板,使其包含到显示所有主题的页面的链接:

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a> -
    <a href="{% url 'learning_logs:topics'%}">Topics</a>
</p>

{% block content %}{% endblock content %}

  我们在主页的链接后面添加了一个连字符,然后添加了一个到显示所有主题的页面的链接。

  现在如果刷新浏览器的主页,将看到链接Topics。单击这个链接,将看到:

18.4.3 显示特定主题的页面

  接下来,我们需要创建一个专注于特定主题的页面——显示该主题的名称及该主题的所有条目。

  1、URL模式

"""定义learning_logs的URL模式"""
from django.conf.urls import url
from .import views

urlpatterns = [
    # 主页
    url(r'^$',views.index,name='index'),
    # 显示所有的主题
    url(r'^topics/$',views.topics,name='topics'),
    # 显示特定主题的详细页面
    url(r'^topics/(?P<topic_id>\d+)/$',views.topic,name='topic'),
]

  2、视图

def topic(request,top_id):
    """显示单个主题及其所有的条目"""
    topic = Topic.objects.get(id=top_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic':topic,'entries':entries}
    return render(request,'learning_logs/topic.html',context)

  date_added前面的减号指定降序排序。

  3、模板

  

{% extends "learning_logs/base.html" %}

{% block content %}
    <p>Topic:{{topic}}</p>
    <p>Entries:</p>
    <ul>
        {% for entry in entries %}
            <li>
                <p>{{ entry.date_added|date:'M d,Y H:i' }}</p>
                <p>{{ entry.text|linebreaks }}</p>
            </li>
        {% empty %}}
            <li>
                There are no entries for this topic yet.
            </li>
        {% endfor %}
    </ul>
{% endblock content %}

  显示当前的主题,它存储在模板变量{{topic}}中。为什么使用变量topic呢?因为它包含在字典context中。

  每个项目列表都将列出两项信息:条目的时间戳和完整的文本。未列出时间戳,我们显示属性gate_added的值。在Django模板中,竖线表示模板过滤器——对模板变量的值进行修改的函数。过滤器linebreaks将包含换行符的长条目转换为浏览器能够理解的格式,一面显示为一个不间断的文本块。

  4、将显示所有主题的页面中的每个主题都设置为连接。

  在浏览器中查看特定主题的页面前,我们需要修改模板topics.html,让每个主题都链接到相应的网页:

{% extends "learning_logs/base.html" %}

{% block content %}
    <p>Topics</p>
    <ul>
        {% for topic in topics %}
            <li>
                <a href="{% url 'learning_logs:topic.id%}">{{ topic }}</a>
            </li>
        {% empty %}}
            <li>No topics have been added yet.</li>
        {% endfor %}
    </ul>
{% endblock content %}

 

 

 

 

 

---恢复内容结束---

posted @ 2019-07-28 17:36  橘子酱ing  阅读(938)  评论(0编辑  收藏  举报